-Fixmes
[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 /**
48  * TODO:
49  * 1. In X-Vine paper, there is no policy defined for replicating the data to
50  * recover in case of peer failure. We can do it in Chord way. In R5N, the key
51  * is hashed and then data is stored according to the key value generated after
52  * hashing.
53  */
54
55 #define DEBUG(...)                                           \
56   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
57
58 /**
59  * Maximum possible fingers (including predecessor) of a peer
60  */
61 #define MAX_FINGERS 65
62
63 /**
64  * Maximum allowed number of pending messages per friend peer.
65  */
66 #define MAXIMUM_PENDING_PER_FRIEND 64
67
68 /**
69  * How long to wait before sending another find finger trail request
70  */
71 #define DHT_FIND_FINGER_TRAIL_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 2)
72
73 /**
74  * How long to wait before sending another verify successor message.
75  */
76 #define DHT_SEND_VERIFY_SUCCESSOR_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 1)
77
78 /**
79  * How long at most to wait for transmission of a request to a friend ?
80  */
81 #define GET_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 2)
82
83 /**
84  * Duration for which I may remain congested.
85  * Note: Its a static value. In future, a peer may do some analysis and calculate
86  * congestion_timeout based on 'some' parameters.
87  */
88 #define CONGESTION_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 2)
89
90 /**
91  * Maximum number of trails allowed to go through a friend.
92  */
93 #define TRAILS_THROUGH_FRIEND_THRESHOLD 64
94
95 /**
96  * Maximum number of trails stored per finger.
97  */
98 #define MAXIMUM_TRAILS_PER_FINGER 1
99
100 /**
101  * Finger map index for predecessor entry in finger table.
102  */
103 #define PREDECESSOR_FINGER_ID 64
104
105 /**
106  * Wrap around in peer identity circle.
107  */
108 #define PEER_IDENTITES_WRAP_AROUND pow(2, 64) - 1
109
110 /**
111  * FIXME: Its use only at 3 places check if you can remove it.
112  * To check if a finger is predecessor or not.
113  */
114 enum GDS_NEIGHBOURS_finger_type
115 {
116   GDS_FINGER_TYPE_PREDECESSOR = 1,
117   GDS_FINGER_TYPE_NON_PREDECESSOR = 0
118 };
119
120 GNUNET_NETWORK_STRUCT_BEGIN
121
122 /**
123  * P2P PUT message
124  */
125 struct PeerPutMessage
126 {
127   /**
128    * Type: #GNUNET_MESSAGE_TYPE_XDHT_P2P_PUT
129    */
130   struct GNUNET_MessageHeader header;
131
132   /**
133    * Processing options
134    */
135   uint32_t options GNUNET_PACKED;
136
137   /**
138    * Content type.
139    */
140   uint32_t block_type GNUNET_PACKED;
141
142   /**
143    * Hop count
144    */
145   uint32_t hop_count GNUNET_PACKED;
146
147   /**
148    * Replication level for this message
149    * In the current implementation, this value is not used.
150    */
151   uint32_t desired_replication_level GNUNET_PACKED;
152
153   /**
154    * Length of the PUT path that follows (if tracked).
155    */
156   uint32_t put_path_length GNUNET_PACKED;
157
158   /**
159    * Best known destination (could be my friend or finger) which should
160    * get this message next.
161    */
162   struct GNUNET_PeerIdentity best_known_destination;
163
164   /**
165    * In case best_known_destination is a finger, then trail to reach
166    * to that finger. Else its default value is 0.
167    */
168   struct GNUNET_HashCode intermediate_trail_id;
169
170   /**
171    * When does the content expire?
172    */
173   struct GNUNET_TIME_AbsoluteNBO expiration_time;
174
175   /**
176    * The key to store the value under.
177    */
178   struct GNUNET_HashCode key GNUNET_PACKED;
179
180   /* put path (if tracked) */
181
182   /* Payload */
183
184 };
185
186 /**
187  * P2P GET message
188  */
189 struct PeerGetMessage
190 {
191   /**
192    * Type: #GNUNET_MESSAGE_TYPE_XDHT_P2P_GET
193    */
194   struct GNUNET_MessageHeader header;
195
196   /**
197    * Processing options
198    */
199   uint32_t options GNUNET_PACKED;
200
201   /**
202    * Desired content type.
203    */
204   uint32_t block_type GNUNET_PACKED;
205
206   /**
207    * Hop count
208    */
209   uint32_t hop_count GNUNET_PACKED;
210
211   /**
212    * Desired replication level for this request.
213    * In the current implementation, this value is not used.
214    */
215   uint32_t desired_replication_level GNUNET_PACKED;
216
217   /**
218    * Total number of peers in get path.
219    */
220   unsigned int get_path_length;
221
222   /**
223    * Best known destination (could be my friend or finger) which should
224    * get this message next.
225    */
226   struct GNUNET_PeerIdentity best_known_destination;
227
228   /**
229    * In case best_known_destination is a finger, then trail to reach
230    * to that finger. Else its default value is 0.
231    */
232   struct GNUNET_HashCode intermediate_trail_id;
233
234   /**
235    * The key we are looking for.
236    */
237   struct GNUNET_HashCode key;
238
239   /* Get path. */
240   /* struct GNUNET_PeerIdentity[]*/
241 };
242
243 /**
244  * P2P Result message
245  */
246 struct PeerGetResultMessage
247 {
248   /**
249    * Type: #GNUNET_MESSAGE_TYPE_XDHT_P2P_GET_RESULT
250    */
251   struct GNUNET_MessageHeader header;
252
253   /**
254    * The type for the data.
255    */
256   uint32_t type GNUNET_PACKED;
257
258   /**
259    * Number of peers recorded in the outgoing path from source to the
260    * stored location of this message.
261    */
262   uint32_t put_path_length GNUNET_PACKED;
263
264   /**
265    * Length of the GET path that follows (if tracked).
266    */
267   uint32_t get_path_length GNUNET_PACKED;
268
269   /**
270    * Peer which queried for get and should get the result.
271    */
272   struct GNUNET_PeerIdentity querying_peer;
273
274   /**
275    * When does the content expire?
276    */
277   struct GNUNET_TIME_Absolute expiration_time;
278
279   /**
280    * The key of the corresponding GET request.
281    */
282   struct GNUNET_HashCode key;
283
284   /* put path (if tracked) */
285
286   /* get path (if tracked) */
287
288   /* Payload */
289
290 };
291
292 /**
293  * P2P Trail setup message
294  */
295 struct PeerTrailSetupMessage
296 {
297   /**
298    * Type: #GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_SETUP
299    */
300   struct GNUNET_MessageHeader header;
301
302   /**
303    * Is source_peer trying to setup the trail to a predecessor or any finger.
304    */
305   uint32_t is_predecessor;
306
307   /**
308    * Peer closest to this value will be our finger.
309    */
310   uint64_t final_destination_finger_value;
311
312   /**
313    * Source peer which wants to setup the trail to one of its finger.
314    */
315   struct GNUNET_PeerIdentity source_peer;
316
317   /**
318    * Best known destination (could be my friend or finger) which should
319    * get this message next.
320    *
321    * FIXME: this could be removed if we include trail_source / trail_dest
322    * in the routing table. This way we save 32 bytes of bandwidth by using
323    * extra 8 bytes of memory (2 * sizeof (GNUNET_PEER_ID))
324    */
325   struct GNUNET_PeerIdentity best_known_destination;
326
327   /**
328    * In case best_known_destination is a finger, then trail id of trail to
329    * reach to this finger.
330    */
331   struct GNUNET_HashCode intermediate_trail_id;
332
333   /**
334    * Trail id for trail which we are trying to setup.
335    */
336   struct GNUNET_HashCode trail_id;
337
338   /* List of peers which are part of trail setup so far.
339    * Trail does NOT include source_peer and peer which will be closest to
340    * ultimate_destination_finger_value.
341    * struct GNUNET_PeerIdentity trail[]
342    */
343 };
344
345 /**
346   * P2P Trail Setup Result message
347  */
348 struct PeerTrailSetupResultMessage
349 {
350
351   /**
352    * Type: #GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_SETUP_RESULT
353    */
354   struct GNUNET_MessageHeader header;
355
356   /**
357    * Finger to which we have found the path.
358    */
359   struct GNUNET_PeerIdentity finger_identity;
360
361   /**
362    * Peer which started trail_setup to find trail to finger_identity
363    */
364   struct GNUNET_PeerIdentity querying_peer;
365
366   /**
367    * Is the trail setup to querying_peer's predecessor or finger?
368    */
369   uint32_t is_predecessor;
370
371   /**
372    * Value to which finger_identity is the closest peer.
373    */
374   uint64_t ulitmate_destination_finger_value;
375
376   /**
377    * Identifier of the trail from querying peer to finger_identity, NOT
378    * including both endpoints.
379    */
380   struct GNUNET_HashCode trail_id;
381
382   /* List of peers which are part of the trail from querying peer to
383    * finger_identity, NOT including both endpoints.
384    * struct GNUNET_PeerIdentity trail[]
385    */
386 };
387
388 /**
389  * P2P Verify Successor Message.
390  */
391 struct PeerVerifySuccessorMessage
392 {
393   /**
394    * Type: #GNUNET_MESSAGE_TYPE_XDHT_P2P_VERIFY_SUCCESSOR
395    */
396   struct GNUNET_MessageHeader header;
397
398   /**
399    * Peer which wants to verify its successor.
400    */
401   struct GNUNET_PeerIdentity source_peer;
402
403   /**
404    * Source Peer's current successor.
405    */
406   struct GNUNET_PeerIdentity successor;
407
408   /**
409    * Identifier of trail to reach from source_peer to successor.
410    */
411   struct GNUNET_HashCode trail_id;
412
413   /* List of the peers which are part of trail to reach  from source_peer
414    * to successor, NOT including them
415    * struct GNUNET_PeerIdentity trail[]
416    */
417 };
418
419 /**
420  * P2P Verify Successor Result Message
421  */
422 struct PeerVerifySuccessorResultMessage
423 {
424   /**
425    * Type: #GNUNET_MESSAGE_TYPE_XDHT_P2P_VERIFY_SUCCESSOR_RESULT
426    */
427   struct GNUNET_MessageHeader header;
428
429   /**
430    * Peer which sent the request to verify its successor.
431    */
432   struct GNUNET_PeerIdentity querying_peer;
433
434   /**
435    * Successor to which PeerVerifySuccessorMessage was sent.
436    */
437   struct GNUNET_PeerIdentity current_successor;
438
439   /**
440    * Current Predecessor of source_successor. It can be same as querying peer
441    * or different. In case it is different then it can be querying_peer's
442    * probable successor.
443    */
444   struct GNUNET_PeerIdentity probable_successor;
445
446   /**
447    * Trail identifier of trail from querying_peer to current_successor.
448    */
449   struct GNUNET_HashCode trail_id;
450
451   /**
452    * Direction in which we are looking at the trail.
453    */
454   uint32_t trail_direction;
455
456   /* In case probable_successor != querying_peer, then trail to reach from
457    * querying_peer to probable_successor, NOT including end points.
458    * struct GNUNET_PeerIdentity trail[]
459    */
460 };
461
462 /**
463  * P2P Notify New Successor Message.
464  */
465 struct PeerNotifyNewSuccessorMessage
466 {
467   /**
468    * Type: #GNUNET_MESSAGE_TYPE_XDHT_P2P_NOTIFY_NEW_SUCCESSOR
469    */
470   struct GNUNET_MessageHeader header;
471
472   /**
473    * Peer which wants to notify its new successor.
474    */
475   struct GNUNET_PeerIdentity source_peer;
476
477   /**
478    * New successor of source_peer.
479    */
480   struct GNUNET_PeerIdentity new_successor;
481
482   /**
483    * Unique identifier of the trail from source_peer to new_successor,
484    * NOT including the endpoints.
485    */
486   struct GNUNET_HashCode trail_id;
487
488   /* List of peers in trail from source_peer to new_successor,
489    * NOT including the endpoints.
490    * struct GNUNET_PeerIdentity trail[]
491    */
492 };
493
494 /**
495  * P2P Trail Compression Message.
496  */
497 struct PeerTrailCompressionMessage
498 {
499   /**
500    * Type: #GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_COMPRESSION
501    */
502   struct GNUNET_MessageHeader header;
503
504   /**
505    * Source peer of this trail.
506    */
507   struct GNUNET_PeerIdentity source_peer;
508
509   /**
510    * Trail from source_peer to destination_peer compressed such that
511    * new_first_friend is the first hop in the trail from source to
512    * destination.
513    */
514   struct GNUNET_PeerIdentity new_first_friend;
515
516   /**
517    * Unique identifier of trail.
518    */
519   struct GNUNET_HashCode trail_id;
520 };
521
522
523 /**
524  * P2P Trail Tear Down message.
525  */
526 struct PeerTrailTearDownMessage
527 {
528   /**
529    * Type: #GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_TEARDOWN
530    */
531   struct GNUNET_MessageHeader header;
532
533   /**
534    * Unique identifier of the trail.
535    */
536   struct GNUNET_HashCode trail_id;
537
538   /**
539    * Direction of trail.
540    */
541   uint32_t trail_direction;
542 };
543
544
545 /**
546  * P2P Trail Rejection Message.
547  */
548 struct PeerTrailRejectionMessage
549 {
550   /**
551    * Type: #GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_SETUP_REJECTION
552    */
553   struct GNUNET_MessageHeader header;
554
555   /**
556    * Peer which wants to set up the trail.
557    */
558   struct GNUNET_PeerIdentity source_peer;
559
560   /**
561    * Peer which sent trail rejection message as it it congested.
562    */
563   struct GNUNET_PeerIdentity congested_peer;
564
565   /**
566    * Peer identity closest to this value will be finger of
567    * source_peer.
568    */
569   uint64_t ultimate_destination_finger_value;
570
571   /**
572    * Is source_peer trying to setup the trail to its predecessor or finger.
573    */
574   uint32_t is_predecessor;
575
576   /**
577    * Identifier for the trail that source peer is trying to setup.
578    */
579   struct GNUNET_HashCode trail_id;
580
581   /**
582    * Relative time for which congested_peer will remain congested.
583    */
584   struct GNUNET_TIME_Relative congestion_time;
585
586   /* Trail_list from source_peer to peer which sent the message for trail setup
587    * to congested peer. This trail does NOT include source_peer.
588    struct GNUNET_PeerIdnetity trail[]*/
589 };
590
591 /**
592  * P2P Add Trail Message.
593  */
594 struct PeerAddTrailMessage
595 {
596   /**
597    * Type: #GNUNET_MESSAGE_TYPE_XDHT_P2P_ADD_TRAIL
598    */
599   struct GNUNET_MessageHeader header;
600
601   /**
602    * Source of the routing trail.
603    */
604   struct GNUNET_PeerIdentity source_peer;
605
606   /**
607    * Destination of the routing trail.
608    */
609   struct GNUNET_PeerIdentity destination_peer;
610
611   /**
612    * Unique identifier of the trail from source_peer to destination_peer,
613    * NOT including the endpoints.
614    */
615   struct GNUNET_HashCode trail_id;
616
617   /* Trail from source peer to destination peer, NOT including them.
618    * struct GNUNET_PeerIdentity trail[]
619    */
620 };
621
622 GNUNET_NETWORK_STRUCT_END
623
624 /**
625  * Linked list of messages to send to a particular other peer.
626  */
627 struct P2PPendingMessage
628 {
629   /**
630    * Pointer to next item in the list
631    */
632   struct P2PPendingMessage *next;
633
634   /**
635    * Pointer to previous item in the list
636    */
637   struct P2PPendingMessage *prev;
638
639   /**
640    * Message importance level.  FIXME: used? useful?
641    */
642   unsigned int importance;
643
644   /**
645    * When does this message time out?
646    */
647   struct GNUNET_TIME_Absolute timeout;
648
649   /**
650    * Actual message to be sent, allocated at the end of the struct:
651    * // msg = (cast) &pm[1];
652    * // memcpy (&pm[1], data, len);
653    */
654   const struct GNUNET_MessageHeader *msg;
655
656 };
657
658 /**
659  *  Entry in friend_peermap.
660  */
661 struct FriendInfo
662 {
663   /**
664    * Friend Identity
665    */
666   struct GNUNET_PeerIdentity id;
667
668   /**
669    * Number of trails for which this friend is the first hop or if the friend
670    * is finger.
671    */
672   unsigned int trails_count;
673
674   /**
675    * Count of outstanding messages for this friend.
676    */
677   unsigned int pending_count;
678
679   /**
680    * In case not 0, then amount of time for which this friend is congested.
681    */
682   struct GNUNET_TIME_Absolute congestion_timestamp;
683
684   /**
685    * Head of pending messages to be sent to this friend.
686    */
687   struct P2PPendingMessage *head;
688
689   /**
690    * Tail of pending messages to be sent to this friend.
691    */
692   struct P2PPendingMessage *tail;
693
694   /**
695    * Core handle for sending messages to this friend.
696    */
697   struct GNUNET_CORE_TransmitHandle *th;
698
699 };
700
701 /**
702  * An individual element of the trail to reach to a finger.
703  */
704 struct Trail_Element
705 {
706   /**
707     * Pointer to next item in the list
708     */
709   struct Trail_Element *next;
710
711   /**
712     * Pointer to prev item in the list
713     */
714   struct Trail_Element *prev;
715
716   /**
717    * An element in this trail.
718    */
719   struct GNUNET_PeerIdentity peer;
720 };
721
722 /**
723  * Information about an individual trail.
724  */
725 struct Trail
726 {
727   /**
728    * Head of trail.
729    */
730   struct Trail_Element *trail_head;
731
732   /**
733    * Tail of trail.
734    */
735   struct Trail_Element *trail_tail;
736
737   /**
738    * Unique identifier of this trail.
739    */
740   struct GNUNET_HashCode trail_id;
741
742   /**
743    * Length of trail pointed
744    */
745   unsigned int trail_length;
746
747   /**
748    * Is there a valid trail entry.
749    */
750   unsigned int is_present;
751 };
752
753 /**
754  * An entry in finger_table
755  */
756 struct FingerInfo
757 {
758   /**
759    * Finger identity.
760    */
761   struct GNUNET_PeerIdentity finger_identity;
762
763   /**
764    * Is any finger stored at this finger index.
765    */
766   unsigned int is_present;
767
768   /**
769    * Index in finger peer map
770    */
771   uint32_t finger_table_index;
772
773   /**
774    * Number of trails setup so far for this finger.
775    * Should not cross MAXIMUM_TRAILS_PER_FINGER.
776    */
777   uint32_t trails_count;
778
779   /**
780    * Array of trails to reach to this finger.
781    */
782   struct Trail trail_list[MAXIMUM_TRAILS_PER_FINGER];
783 };
784
785
786 /**
787  * Stores information about the peer which is closest to destination_finger_value.
788  * 'closest' can be either successor or predecessor depending on is_predecessor
789  * flag.
790  */
791 struct Closest_Peer
792 {
793   /**
794    * Destination finger value.
795    */
796   uint64_t destination_finger_value;
797
798   /**
799    * Is finger_value a predecessor or any other finger.
800    */
801   unsigned int is_predecessor;
802
803   /**
804    * Trail id to reach to peer.
805    * In case peer is my identity or friend, it is set to 0.
806    */
807   struct GNUNET_HashCode trail_id;
808
809   /**
810    * Next destination. In case of friend and my_identity , it is same as next_hop
811    * In case of finger it is finger identity.
812    */
813   struct GNUNET_PeerIdentity best_known_destination;
814
815   /**
816    * In case best_known_destination is a finger, then first friend in the trail
817    * to reach to it. In other case, same as best_known_destination.
818    */
819   struct GNUNET_PeerIdentity next_hop;
820 };
821
822
823 /**
824  * Data structure to store the trail chosen to reach to finger.
825  */
826 struct Selected_Finger_Trail
827 {
828   /**
829    * First friend in the trail to reach finger.
830    */
831   struct FriendInfo friend;
832
833   /**
834    * Identifier of this trail.
835    */
836   struct GNUNET_HashCode trail_id;
837
838   /**
839    * Total number of peers in this trail.
840    */
841   unsigned int trail_length;
842 };
843
844 /**
845  * Task that sends FIND FINGER TRAIL requests. This task is started when we have
846  * get our first friend.
847  */
848 static GNUNET_SCHEDULER_TaskIdentifier find_finger_trail_task;
849
850 /**
851  * Task that sends verify successor message. This task is started when we get
852  * our successor for the first time.
853  */
854 static GNUNET_SCHEDULER_TaskIdentifier send_verify_successor_task;
855
856 /**
857  * Identity of this peer.
858  */
859 static struct GNUNET_PeerIdentity my_identity;
860
861 /**
862  * Peer map of all the friends of a peer
863  */
864 static struct GNUNET_CONTAINER_MultiPeerMap *friend_peermap;
865
866 /**
867  * Array of all the fingers.
868  */
869 static struct FingerInfo finger_table [MAX_FINGERS];
870
871 /**
872  * Handle to CORE.
873  */
874 static struct GNUNET_CORE_Handle *core_api;
875
876 /**
877  * Handle for the statistics service.
878  */
879 extern struct GNUNET_STATISTICS_Handle *GDS_stats;
880
881 /**
882  * The current finger index that we have want to find trail to. We start the
883  * search with value = 0, i.e. successor  and then go to PREDCESSOR_FINGER_ID
884  * and decrement it. For any index 63 <= index < 0, if finger is same as successor,
885  * we reset this index to 0.
886  */
887 static unsigned int current_search_finger_index;
888
889 /**
890  * Should we store our topology predecessor and successor IDs into statistics?
891  */
892 unsigned int track_topology;
893
894 /**
895  * Called when core is ready to send a message we asked for
896  * out to the destination.
897  *
898  * @param cls the 'struct FriendInfo' of the target friend
899  * @param size number of bytes available in buf
900  * @param buf where the callee should write the message
901  * @return number of bytes written to buf
902  */
903 static size_t
904 core_transmit_notify (void *cls, size_t size, void *buf)
905 {
906   struct FriendInfo *peer = cls;
907   char *cbuf = buf;
908   struct P2PPendingMessage *pending;
909   size_t off;
910   size_t msize;
911
912   peer->th = NULL;
913   while ((NULL != (pending = peer->head)) &&
914          (0 == GNUNET_TIME_absolute_get_remaining (pending->timeout).rel_value_us))
915   {
916     peer->pending_count--;
917     GNUNET_CONTAINER_DLL_remove (peer->head, peer->tail, pending);
918     GNUNET_free (pending);
919   }
920   if (NULL == pending)
921   {
922     /* no messages pending */
923     return 0;
924   }
925   if (NULL == buf)
926   {
927     peer->th =
928         GNUNET_CORE_notify_transmit_ready (core_api, GNUNET_NO,
929                                            GNUNET_CORE_PRIO_BEST_EFFORT,
930                                            GNUNET_TIME_absolute_get_remaining
931                                            (pending->timeout), &peer->id,
932                                            ntohs (pending->msg->size),
933                                            &core_transmit_notify, peer);
934     GNUNET_break (NULL != peer->th);
935     return 0;
936   }
937   off = 0;
938   while ((NULL != (pending = peer->head)) &&
939          (size - off >= (msize = ntohs (pending->msg->size))))
940   {
941     GNUNET_STATISTICS_update (GDS_stats,
942                               gettext_noop
943                               ("# Bytes transmitted to other peers"), msize,
944                               GNUNET_NO);
945     memcpy (&cbuf[off], pending->msg, msize);
946     off += msize;
947     peer->pending_count--;
948     GNUNET_CONTAINER_DLL_remove (peer->head, peer->tail, pending);
949     GNUNET_free (pending);
950   }
951   if (peer->head != NULL)
952   {
953     peer->th =
954         GNUNET_CORE_notify_transmit_ready (core_api, GNUNET_NO,
955                                            GNUNET_CORE_PRIO_BEST_EFFORT,
956                                            GNUNET_TIME_absolute_get_remaining
957                                            (pending->timeout), &peer->id, msize,
958                                            &core_transmit_notify, peer);
959     GNUNET_break (NULL != peer->th);
960   }
961   return off;
962 }
963
964
965 /**
966  * Transmit all messages in the friend's message queue.
967  *
968  * @param peer message queue to process
969  */
970 static void
971 process_friend_queue (struct FriendInfo *peer)
972 {
973   struct P2PPendingMessage *pending;
974
975   if (NULL == (pending = peer->head))
976   {
977     return;
978   }
979   if (NULL != peer->th)
980   {
981     return;
982   }
983  
984   peer->th =
985       GNUNET_CORE_notify_transmit_ready (core_api, GNUNET_NO,
986                                          pending->importance,
987                                          GNUNET_TIME_absolute_get_remaining
988                                          (pending->timeout), &peer->id,
989                                          ntohs (pending->msg->size),
990                                          &core_transmit_notify, peer);
991   GNUNET_break (NULL != peer->th);
992 }
993
994
995 /**
996  * Construct a trail setup message and forward it to target_friend
997  * @param source_peer Peer which wants to setup the trail
998  * @param ultimate_destination_finger_value Peer identity closest to this value
999  *                                          will be finger to @a source_peer
1000  * @param best_known_destination Best known destination (could be finger or friend)
1001  *                               which should get this message. In case it is
1002  *                               friend, then it is same as target_friend
1003  * @param target_friend Friend to which message is forwarded now.
1004  * @param trail_length Total number of peers in trail setup so far.
1005  * @param trail_peer_list Trail setup so far
1006  * @param is_predecessor Is @a source_peer looking for trail to a predecessor or not.
1007  * @param trail_id Unique identifier for the trail we are trying to setup.
1008  * @param intermediate_trail_id Trail id of intermediate trail to reach to
1009  *                              best_known_destination when its a finger. If not
1010  *                              used then set to 0.
1011  */
1012 void
1013 GDS_NEIGHBOURS_send_trail_setup (struct GNUNET_PeerIdentity source_peer,
1014                                  uint64_t ultimate_destination_finger_value,
1015                                  struct GNUNET_PeerIdentity best_known_destination,
1016                                  struct FriendInfo *target_friend,
1017                                  unsigned int trail_length,
1018                                  const struct GNUNET_PeerIdentity *trail_peer_list,
1019                                  unsigned int is_predecessor,
1020                                  struct GNUNET_HashCode trail_id,
1021                                  struct GNUNET_HashCode intermediate_trail_id)
1022 {
1023   struct P2PPendingMessage *pending;
1024   struct PeerTrailSetupMessage *tsm;
1025   struct GNUNET_PeerIdentity *peer_list;
1026   size_t msize;
1027
1028   msize = sizeof (struct PeerTrailSetupMessage) +
1029           (trail_length * sizeof (struct GNUNET_PeerIdentity));
1030
1031   if (msize >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
1032   {
1033     GNUNET_break (0);
1034     return;
1035   }
1036
1037   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1038   {
1039     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1040                                 1, GNUNET_NO);
1041   }
1042
1043   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
1044   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1045   tsm = (struct PeerTrailSetupMessage *) &pending[1];
1046   pending->msg = &tsm->header;
1047   tsm->header.size = htons (msize);
1048   tsm->header.type = htons (GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_SETUP);
1049   tsm->final_destination_finger_value = GNUNET_htonll (ultimate_destination_finger_value);
1050   tsm->source_peer = source_peer;
1051   tsm->best_known_destination = best_known_destination;
1052   tsm->is_predecessor = htonl (is_predecessor);
1053   tsm->trail_id = trail_id;
1054   tsm->intermediate_trail_id = intermediate_trail_id;
1055
1056   if (trail_length > 0)
1057   {
1058     peer_list = (struct GNUNET_PeerIdentity *) &tsm[1];
1059     memcpy (peer_list, trail_peer_list, trail_length * sizeof(struct GNUNET_PeerIdentity));
1060   }
1061
1062   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1063   target_friend->pending_count++;
1064   process_friend_queue (target_friend);
1065 }
1066
1067
1068 /**
1069  * Construct a trail setup result message and forward it to target friend.
1070  * @param querying_peer Peer which sent the trail setup request and should get
1071  *                      the result back.
1072  * @param Finger Peer to which the trail has been setup to.
1073  * @param target_friend Friend to which this message should be forwarded.
1074  * @param trail_length Numbers of peers in the trail.
1075  * @param trail_peer_list Peers which are part of the trail from
1076  *                        querying_peer to Finger, NOT including them.
1077  * @param is_predecessor Is @a Finger predecessor to @a querying_peer ?
1078  * @param ultimate_destination_finger_value Value to which @a finger is the closest
1079  *                                          peer.
1080  * @param trail_id Unique identifier of the trail.
1081  */
1082 void
1083 GDS_NEIGHBOURS_send_trail_setup_result (struct GNUNET_PeerIdentity querying_peer,
1084                                         struct GNUNET_PeerIdentity finger,
1085                                         struct FriendInfo *target_friend,
1086                                         unsigned int trail_length,
1087                                         const struct GNUNET_PeerIdentity *trail_peer_list,
1088                                         unsigned int is_predecessor,
1089                                         uint64_t ultimate_destination_finger_value,
1090                                         struct GNUNET_HashCode trail_id)
1091 {
1092   struct P2PPendingMessage *pending;
1093   struct PeerTrailSetupResultMessage *tsrm;
1094   struct GNUNET_PeerIdentity *peer_list;
1095   size_t msize;
1096
1097   msize = sizeof (struct PeerTrailSetupResultMessage) +
1098           (trail_length * sizeof (struct GNUNET_PeerIdentity));
1099
1100   if (msize >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
1101   {
1102     GNUNET_break (0);
1103     return;
1104   }
1105
1106   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1107   {
1108     GNUNET_STATISTICS_update (GDS_stats,
1109                               gettext_noop ("# P2P messages dropped due to full queue"),
1110                               1, GNUNET_NO);
1111   }
1112
1113   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
1114   pending->importance = 0;
1115   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1116   tsrm = (struct PeerTrailSetupResultMessage *) &pending[1];
1117   pending->msg = &tsrm->header;
1118   tsrm->header.size = htons (msize);
1119   tsrm->header.type = htons (GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_SETUP_RESULT);
1120   tsrm->querying_peer = querying_peer;
1121   tsrm->finger_identity = finger;
1122   tsrm->is_predecessor = htonl (is_predecessor);
1123   tsrm->trail_id = trail_id;
1124   tsrm->ulitmate_destination_finger_value =
1125           GNUNET_htonll (ultimate_destination_finger_value);
1126   peer_list = (struct GNUNET_PeerIdentity *) &tsrm[1];
1127
1128   memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
1129
1130   /* Send the message to chosen friend. */
1131   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1132   target_friend->pending_count++;
1133   process_friend_queue (target_friend);
1134 }
1135
1136
1137 /**
1138  * Send trail rejection message to target friend
1139  * @param source_peer Peer which is trying to setup the trail.
1140  * @param ultimate_destination_finger_value Peer closest to this value will be
1141  *                                          @a source_peer's finger
1142  * @param congested_peer Peer which sent this message as it is congested.
1143  * @param is_predecessor Is source_peer looking for trail to a predecessor or not.
1144  * @param trail_peer_list Trails seen so far in trail setup before getting rejected
1145  *                        by congested_peer. This does NOT include @a source_peer
1146  *                        and congested_peer.
1147  * @param trail_length Total number of peers in trail_peer_list, NOT including
1148  *                     @a source_peer and @a congested_peer
1149  * @param trail_id Unique identifier of this trail.
1150  * @param congestion_timeout Duration given by congested peer as an estimate of
1151  *                           how long it may remain congested.
1152  */
1153 void
1154 GDS_NEIGHBOURS_send_trail_rejection (struct GNUNET_PeerIdentity source_peer,
1155                                      uint64_t ultimate_destination_finger_value,
1156                                      struct GNUNET_PeerIdentity congested_peer,
1157                                      unsigned int is_predecessor,
1158                                      const struct GNUNET_PeerIdentity *trail_peer_list,
1159                                      unsigned int trail_length,
1160                                      struct GNUNET_HashCode trail_id,
1161                                      struct FriendInfo *target_friend,
1162                                      const struct GNUNET_TIME_Relative congestion_timeout)
1163 {
1164   struct PeerTrailRejectionMessage *trm;
1165   struct P2PPendingMessage *pending;
1166   struct GNUNET_PeerIdentity *peer_list;
1167   size_t msize;
1168
1169   msize = sizeof (struct PeerTrailRejectionMessage) +
1170           (trail_length * sizeof (struct GNUNET_PeerIdentity));
1171
1172   if (msize >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
1173   {
1174     GNUNET_break (0);
1175     return;
1176   }
1177
1178   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1179   {
1180     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1181                                 1, GNUNET_NO);
1182   }
1183
1184   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
1185   pending->importance = 0;
1186   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1187   trm = (struct PeerTrailRejectionMessage *)&pending[1];
1188   pending->msg = &trm->header;
1189   trm->header.size = htons (msize);
1190   trm->header.type = htons (GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_SETUP_REJECTION);
1191   trm->source_peer = source_peer;
1192   trm->congested_peer = congested_peer;
1193   trm->congestion_time = congestion_timeout;
1194   trm->is_predecessor = htonl (is_predecessor);
1195   trm->trail_id = trail_id;
1196   trm->ultimate_destination_finger_value =
1197           GNUNET_htonll (ultimate_destination_finger_value);
1198
1199   peer_list = (struct GNUNET_PeerIdentity *) &trm[1];
1200   if (trail_length > 0)
1201   {
1202     memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
1203   }
1204
1205   /* Send the message to chosen friend. */
1206   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1207   target_friend->pending_count++;
1208   process_friend_queue (target_friend);
1209 }
1210
1211
1212 /**
1213  * Construct a verify successor message and forward it to target_friend.
1214  * @param source_peer Peer which wants to verify its successor.
1215  * @param successor Peer which is @a source_peer's current successor.
1216  * @param trail_id Unique Identifier of trail from @a source_peer to @a successor,
1217  *                 NOT including them.
1218  * @param trail List of peers which are part of trail to reach from @a source_peer
1219  *              to @a successor, NOT including them.
1220  * @param trail_length Total number of peers in @a trail.
1221  * @param target_friend Next friend to get this message.
1222  */
1223 void
1224 GDS_NEIGHBOURS_send_verify_successor_message (struct GNUNET_PeerIdentity source_peer,
1225                                               struct GNUNET_PeerIdentity successor,
1226                                               struct GNUNET_HashCode trail_id,
1227                                               struct GNUNET_PeerIdentity *trail,
1228                                               unsigned int trail_length,
1229                                               struct FriendInfo *target_friend)
1230 {
1231   struct PeerVerifySuccessorMessage *vsm;
1232   struct P2PPendingMessage *pending;
1233   struct GNUNET_PeerIdentity *peer_list;
1234   size_t msize;
1235
1236   msize = sizeof (struct PeerVerifySuccessorMessage) +
1237          (trail_length * sizeof (struct GNUNET_PeerIdentity));;
1238   if (msize >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
1239   {
1240     GNUNET_break (0);
1241     return;
1242   }
1243
1244   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1245   {
1246     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1247                                 1, GNUNET_NO);
1248   }
1249
1250   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
1251   pending->importance = 0;    /* FIXME */
1252   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1253   vsm = (struct PeerVerifySuccessorMessage *) &pending[1];
1254   pending->msg = &vsm->header;
1255   vsm->header.size = htons (msize);
1256   vsm->header.type = htons (GNUNET_MESSAGE_TYPE_XDHT_P2P_VERIFY_SUCCESSOR);
1257   vsm->source_peer = source_peer;
1258   vsm->successor = successor;
1259   vsm->trail_id = trail_id;
1260   peer_list = (struct GNUNET_PeerIdentity *) &vsm[1];
1261   memcpy (peer_list, trail, trail_length * sizeof (struct GNUNET_PeerIdentity));
1262
1263   /* Send the message to chosen friend. */
1264   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1265   target_friend->pending_count++;
1266   process_friend_queue (target_friend);
1267 }
1268
1269
1270 /**
1271  * FIXME: In every function we pass target friend except for this one.
1272  * so, either change everything or this one. also, should se just store
1273  * the pointer to friend in routing table rather than gnunet_peeridentity.
1274  * if yes then we should keep friend info in.h  andmake lot of changes.
1275  * Construct a trail teardown message and forward it to target friend.
1276  * @param trail_id Unique identifier of the trail.
1277  * @param trail_direction Direction of trail.
1278  * @param target_friend Friend to get this message.
1279  */
1280 void
1281 GDS_NEIGHBOURS_send_trail_teardown (struct GNUNET_HashCode trail_id,
1282                                     unsigned int trail_direction,
1283                                     struct GNUNET_PeerIdentity peer)
1284 {
1285   struct PeerTrailTearDownMessage *ttdm;
1286   struct P2PPendingMessage *pending;
1287   struct FriendInfo *target_friend;
1288   size_t msize;
1289
1290   msize = sizeof (struct PeerTrailTearDownMessage);
1291
1292   if (msize >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
1293   {
1294     GNUNET_break (0);
1295     return;
1296   }
1297
1298   /*FIXME:In what case friend can be null. ?*/
1299   if (NULL == (target_friend =
1300                  GNUNET_CONTAINER_multipeermap_get (friend_peermap, &peer)));
1301   return;
1302
1303   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1304   {
1305     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1306                                 1, GNUNET_NO);
1307   }
1308
1309   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
1310   pending->importance = 0;    /* FIXME */
1311   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1312   ttdm = (struct PeerTrailTearDownMessage *) &pending[1];
1313   pending->msg = &ttdm->header;
1314   ttdm->header.size = htons (msize);
1315   ttdm->header.type = htons (GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_TEARDOWN);
1316   ttdm->trail_id = trail_id;
1317   ttdm->trail_direction = htonl (trail_direction);
1318
1319   /* Send the message to chosen friend. */
1320   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1321   target_friend->pending_count++;
1322   process_friend_queue (target_friend);
1323 }
1324
1325
1326 /**
1327  * Construct a verify successor result message and send it to target_friend
1328  * @param querying_peer Peer which sent the verify successor message.
1329  * @param source_successor Current_successor of @a querying_peer.
1330  * @param current_predecessor Current predecessor of @a successor. Could be same
1331  *                            or different from @a querying_peer.
1332  * @param trail_id Unique identifier of the trail from @a querying_peer to
1333  *                 @a successor, NOT including them.
1334  * @param trail List of peers which are part of trail from @a querying_peer to
1335  *                 @a successor, NOT including them.
1336  * @param trail_length Total number of peers in @a trail
1337  * @param trail_direction Direction in which we are sending the message. In this
1338  *                        case we are sending result from @a successor to @a querying_peer.
1339  * @param target_friend Next friend to get this message.
1340  */
1341 void
1342 GDS_NEIGHBOURS_send_verify_successor_result (struct GNUNET_PeerIdentity querying_peer,
1343                                              struct GNUNET_PeerIdentity current_successor,
1344                                              struct GNUNET_PeerIdentity probable_successor,
1345                                              struct GNUNET_HashCode trail_id,
1346                                              const struct GNUNET_PeerIdentity *trail,
1347                                              unsigned int trail_length,
1348                                              enum GDS_ROUTING_trail_direction trail_direction,
1349                                              struct FriendInfo *target_friend)
1350 {
1351   struct PeerVerifySuccessorResultMessage *vsmr;
1352   struct P2PPendingMessage *pending;
1353   struct GNUNET_PeerIdentity *peer_list;
1354   size_t msize;
1355
1356   msize = sizeof (struct PeerVerifySuccessorResultMessage) +
1357           (trail_length * sizeof(struct GNUNET_PeerIdentity));
1358
1359   if (msize >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
1360   {
1361     GNUNET_break (0);
1362     return;
1363   }
1364
1365   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1366   {
1367     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1368                                 1, GNUNET_NO);
1369   }
1370
1371   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
1372   pending->importance = 0;    /* FIXME */
1373   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1374   vsmr = (struct PeerVerifySuccessorResultMessage *) &pending[1];
1375   pending->msg = &vsmr->header;
1376   vsmr->header.size = htons (msize);
1377   vsmr->header.type = htons (GNUNET_MESSAGE_TYPE_XDHT_P2P_VERIFY_SUCCESSOR_RESULT);
1378   vsmr->querying_peer = querying_peer;
1379   vsmr->current_successor = current_successor;
1380   vsmr->probable_successor = probable_successor;
1381   vsmr->trail_direction = htonl (trail_direction);
1382   vsmr->trail_id = trail_id; 
1383   peer_list = (struct GNUNET_PeerIdentity *) &vsmr[1];
1384   memcpy (peer_list, trail, trail_length * sizeof (struct GNUNET_PeerIdentity));
1385   
1386    /* Send the message to chosen friend. */
1387   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1388   target_friend->pending_count++;
1389   process_friend_queue (target_friend);
1390 }
1391
1392
1393 /**
1394  * Construct a notify new successor message and send it to target_friend
1395  * @param source_peer Peer which wants to notify to its new successor that it
1396  *                    could be its predecessor.
1397  * @param successor New successor of @a source_peer
1398  * @param successor_trail List of peers in Trail to reach from
1399  *                            @a source_peer to @a new_successor, NOT including
1400  *                            the endpoints.
1401  * @param successor_trail_length Total number of peers in @a new_successor_trail.
1402  * @param successor_trail_id Unique identifier of @a new_successor_trail.
1403  * @param target_friend Next friend to get this message.
1404  */
1405 void
1406 GDS_NEIGHBOURS_send_notify_new_successor (struct GNUNET_PeerIdentity source_peer,
1407                                           struct GNUNET_PeerIdentity successor,
1408                                           const struct GNUNET_PeerIdentity *successor_trail,
1409                                           unsigned int successor_trail_length,
1410                                           struct GNUNET_HashCode succesor_trail_id,
1411                                           struct FriendInfo *target_friend)
1412 {
1413   struct PeerNotifyNewSuccessorMessage *nsm;
1414   struct P2PPendingMessage *pending;
1415   struct GNUNET_PeerIdentity *peer_list;
1416   size_t msize;
1417
1418   msize = sizeof (struct PeerNotifyNewSuccessorMessage) +
1419           (successor_trail_length * sizeof(struct GNUNET_PeerIdentity));
1420
1421   if (msize >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
1422   {
1423     GNUNET_break (0);
1424     return;
1425   }
1426
1427   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1428   {
1429     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1430                                 1, GNUNET_NO);
1431   }
1432   
1433   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
1434   pending->importance = 0;    /* FIXME */
1435   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1436   nsm = (struct PeerNotifyNewSuccessorMessage *) &pending[1];
1437   pending->msg = &nsm->header;
1438   nsm->header.size = htons (msize);
1439   nsm->header.type = htons (GNUNET_MESSAGE_TYPE_XDHT_P2P_NOTIFY_NEW_SUCCESSOR);
1440   nsm->new_successor = successor;
1441   nsm->source_peer = source_peer;
1442   nsm->trail_id = succesor_trail_id;
1443
1444   peer_list = (struct GNUNET_PeerIdentity *) &nsm[1];
1445   memcpy (peer_list, successor_trail,
1446           successor_trail_length * sizeof (struct GNUNET_PeerIdentity));
1447  
1448    /* Send the message to chosen friend. */
1449   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1450   target_friend->pending_count++;
1451   process_friend_queue (target_friend);
1452 }
1453
1454
1455 /**
1456  * Construct an add_trail message and send it to target_friend
1457  * @param source_peer Source of the trail.
1458  * @param destination_peer Destination of the trail.
1459  * @param trail_id Unique identifier of the trail from
1460  *                 @a source_peer to @a destination_peer, NOT including the endpoints.
1461  * @param trail List of peers in Trail from @a source_peer to @a destination_peer,
1462  *              NOT including the endpoints.
1463  * @param trail_length Total number of peers in @a trail.
1464  * @param target_friend Next friend to get this message.
1465  */
1466 void
1467 GDS_NEIGHBOURS_send_add_trail (struct GNUNET_PeerIdentity source_peer,
1468                                struct GNUNET_PeerIdentity destination_peer,
1469                                struct GNUNET_HashCode trail_id,
1470                                const struct GNUNET_PeerIdentity *trail,
1471                                unsigned int trail_length,
1472                                struct FriendInfo *target_friend)
1473 {
1474   struct PeerAddTrailMessage *adm;
1475   struct GNUNET_PeerIdentity *peer_list;
1476   struct P2PPendingMessage *pending;
1477   size_t msize;
1478
1479   msize = sizeof (struct PeerAddTrailMessage) +
1480           (trail_length * sizeof(struct GNUNET_PeerIdentity));
1481
1482   if (msize >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
1483   {
1484     GNUNET_break (0);
1485     return;
1486   }
1487
1488   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1489   {
1490     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1491                                 1, GNUNET_NO);
1492   }
1493
1494   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
1495   pending->importance = 0;    /* FIXME */
1496   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1497   adm = (struct PeerAddTrailMessage *) &pending[1];
1498   pending->msg = &adm->header;
1499   adm->header.size = htons (msize);
1500   adm->header.type = htons (GNUNET_MESSAGE_TYPE_XDHT_P2P_ADD_TRAIL);
1501   adm->source_peer = source_peer;
1502   adm->destination_peer = destination_peer;
1503   adm->trail_id = trail_id;
1504   peer_list = (struct GNUNET_PeerIdentity *)&adm[1];
1505   memcpy (peer_list, trail, sizeof (struct GNUNET_PeerIdentity) * trail_length);
1506   
1507   /* Send the message to chosen friend. */
1508   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1509   target_friend->pending_count++;
1510   process_friend_queue (target_friend);
1511
1512 }
1513
1514
1515 /**
1516  * Construct a trail compression message and send it to target_friend.
1517  * @param source_peer Source of the trail.
1518  * @param trail_id Unique identifier of trail.
1519  * @param first_friend First hop in compressed trail to reach from source to finger
1520  * @param target_friend Next friend to get this message.
1521  */
1522 void
1523 GDS_NEIGHBOURS_send_trail_compression (struct GNUNET_PeerIdentity source_peer,
1524                                        struct GNUNET_HashCode trail_id,
1525                                        struct GNUNET_PeerIdentity first_friend,
1526                                        struct FriendInfo *target_friend)
1527 {
1528   struct P2PPendingMessage *pending;
1529   struct PeerTrailCompressionMessage *tcm;
1530   size_t msize;
1531
1532   msize = sizeof (struct PeerTrailCompressionMessage);
1533
1534   if (msize >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
1535   {
1536     GNUNET_break (0);
1537     return;
1538   }
1539
1540   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1541   {
1542     GNUNET_STATISTICS_update (GDS_stats,
1543                               gettext_noop ("# P2P messages dropped due to full queue"),
1544                                                       1, GNUNET_NO);
1545   }
1546
1547   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
1548   pending->importance = 0;    /* FIXME */
1549   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1550   tcm = (struct PeerTrailCompressionMessage *) &pending[1];
1551   pending->msg = &tcm->header;
1552   tcm->header.size = htons (msize);
1553   tcm->header.type = htons (GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_COMPRESSION);
1554   tcm->source_peer = source_peer;
1555   tcm->new_first_friend = first_friend;
1556   tcm->trail_id = trail_id;
1557
1558   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1559   target_friend->pending_count++;
1560   process_friend_queue (target_friend);
1561
1562 }
1563
1564
1565 /**
1566  * Search my location in trail. In case I am present more than once in the
1567  * trail (can happen during trail setup), then return my lowest index.
1568  * @param trail List of peers
1569  * @return my_index if found
1570  *         -1 if no entry found.
1571  */
1572 static int
1573 search_my_index (const struct GNUNET_PeerIdentity *trail,
1574                  int trail_length)
1575 {
1576   int i;
1577
1578   for (i = 0; i < trail_length; i++)
1579   {
1580     if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &trail[i]))
1581       return i;
1582   }
1583
1584   return -1;
1585 }
1586
1587
1588 /**
1589  * Check if the friend is congested or have reached maximum number of trails
1590  * it can be part of of.
1591  * @param friend Friend to be checked.
1592  * @return #GNUNET_NO if friend is not congested or have not crossed threshold.
1593  *         #GNUNET_YES if friend is either congested or have crossed threshold
1594  */
1595 static int
1596 is_friend_congested (struct FriendInfo *friend)
1597 {
1598   if ((TRAILS_THROUGH_FRIEND_THRESHOLD > friend->trails_count) &&
1599       ((0 == GNUNET_TIME_absolute_get_remaining
1600              (friend->congestion_timestamp).rel_value_us)))
1601     return GNUNET_NO;
1602   else
1603     return GNUNET_YES;
1604 }
1605
1606
1607 /**
1608  * Select closest finger to value.
1609  * @param peer1 First peer
1610  * @param peer2 Second peer
1611  * @param value Value to be compare
1612  * @return Closest peer
1613  */
1614 const static struct GNUNET_PeerIdentity *
1615 select_closest_finger (const struct GNUNET_PeerIdentity *peer1,
1616                        const struct GNUNET_PeerIdentity *peer2,
1617                        uint64_t value)
1618 {
1619   uint64_t peer1_value;
1620   uint64_t peer2_value;
1621
1622   memcpy (&peer1_value, peer1, sizeof (uint64_t));
1623   memcpy (&peer2_value, peer2, sizeof (uint64_t));
1624   peer1_value = GNUNET_ntohll (peer1_value);
1625   peer2_value = GNUNET_ntohll (peer2_value);
1626
1627   if (peer1_value == value)
1628   {
1629     return peer1;
1630   }
1631
1632   if (peer2_value == value)
1633   {
1634     return peer2;
1635   }
1636
1637   if (peer2_value < peer1_value)
1638   {
1639     if ((peer2_value < value) && (value < peer1_value))
1640     {
1641       return peer1;
1642     }
1643     else if (((peer1_value < value) && (value < PEER_IDENTITES_WRAP_AROUND)) ||
1644              ((0 < value) && (value < peer2_value)))
1645     {
1646       return peer2;
1647     }
1648   }
1649
1650   if (peer1_value < peer2_value)
1651   {
1652     if ((peer1_value < value) && (value < peer2_value))
1653     {
1654       return peer2;
1655     }
1656     else if (((peer2_value < value) && (value < PEER_IDENTITES_WRAP_AROUND)) ||
1657              ((0 < value) && (value < peer1_value)))
1658     {
1659       return peer1;
1660     }
1661   }
1662   return NULL;
1663 }
1664
1665
1666 /**
1667  * Select closest predecessor to value.
1668  * @param peer1 First peer
1669  * @param peer2 Second peer
1670  * @param value Value to be compare
1671  * @return Peer which precedes value in the network.
1672  */
1673 const static struct GNUNET_PeerIdentity *
1674 select_closest_predecessor (const struct GNUNET_PeerIdentity *peer1,
1675                             const struct GNUNET_PeerIdentity *peer2,
1676                             uint64_t value)
1677 {
1678   uint64_t peer1_value;
1679   uint64_t peer2_value;
1680
1681   memcpy (&peer1_value, peer1, sizeof (uint64_t));
1682   memcpy (&peer2_value, peer2, sizeof (uint64_t));
1683   peer1_value = GNUNET_ntohll (peer1_value);
1684   peer2_value = GNUNET_ntohll (peer2_value);
1685
1686   if (peer1_value == value)
1687     return peer1;
1688
1689   if (peer2_value == value)
1690     return peer2;
1691
1692   if (peer1_value < peer2_value)
1693   {
1694     if ((peer1_value < value) && (value < peer2_value))
1695     {
1696       return peer1;
1697     }
1698     else if (((peer2_value < value) && (value < PEER_IDENTITES_WRAP_AROUND)) ||
1699              ((PEER_IDENTITES_WRAP_AROUND > value) && (value < peer1_value)))
1700     {
1701       return peer2;
1702     }
1703   }
1704
1705   if (peer2_value < peer1_value)
1706   {
1707     if ((peer2_value < value) && (value < peer1_value))
1708     {
1709       return peer2;
1710     }
1711     else if (((peer1_value < value) && (value < PEER_IDENTITES_WRAP_AROUND)) ||
1712              ((PEER_IDENTITES_WRAP_AROUND > value) && (value < peer2_value)))
1713     {
1714       return peer1;
1715     }
1716   }
1717   return NULL;
1718 }
1719
1720 #if 0
1721 /**
1722  * This is a test function to print all the entries of friend table.
1723  */
1724 static void
1725 test_friend_peermap_print ()
1726 {
1727   struct FriendInfo *friend;
1728   struct GNUNET_CONTAINER_MultiPeerMapIterator *friend_iter;
1729   struct GNUNET_PeerIdentity print_peer;
1730   struct GNUNET_PeerIdentity key_ret;
1731   int i;
1732
1733   print_peer = my_identity;
1734   FPRINTF (stderr,_("\nSUPU************  FRIEND_PEERMAP of %s"),GNUNET_i2s(&print_peer));
1735   friend_iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap);
1736
1737   for (i = 0; i < GNUNET_CONTAINER_multipeermap_size (friend_peermap); i++)
1738   {
1739     if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (friend_iter,
1740                                                                   &key_ret,
1741                                                                   (const void **)&friend))
1742     {
1743       memcpy (&print_peer, &key_ret, sizeof (struct GNUNET_PeerIdentity));
1744       FPRINTF (stderr,_("\nSUPU %s, %s, %d, friend = %s, friend->trails_count = %d"),
1745               __FILE__, __func__,__LINE__, GNUNET_i2s(&print_peer), friend->trails_count);
1746     }
1747   }
1748 }
1749
1750
1751
1752 /**
1753  * This is a test function, to print all the entries of finger table.
1754  */
1755 static void
1756 test_finger_table_print()
1757 {
1758   struct FingerInfo *finger;
1759   struct GNUNET_PeerIdentity print_peer;
1760   //struct Trail *trail;
1761   int i;
1762   //int j;
1763   //int k;
1764   print_peer = my_identity;
1765   FPRINTF (stderr,_("\nSUPU************  FINGER_TABLE of %s"),GNUNET_i2s(&print_peer));
1766   for (i = 0; i < MAX_FINGERS; i++)
1767   {
1768     finger = &finger_table[i];
1769
1770     if (GNUNET_NO == finger->is_present)
1771       continue;
1772
1773     print_peer = finger->finger_identity;
1774     FPRINTF (stderr,_("\nSUPU %s, %s, %d, finger_table[%d] = %s, trails_count = %d"),
1775             __FILE__, __func__,__LINE__,i,GNUNET_i2s (&print_peer), finger->trails_count);
1776
1777 #if 0
1778     for (j = 0; j < finger->trails_count; j++)
1779     {
1780       trail = &finger->trail_list[j];
1781       FPRINTF (stderr,_("\nSUPU %s, %s, %d, trail_id[%d]=%s"),__FILE__, __func__,__LINE__,j, GNUNET_h2s(&trail->trail_id));
1782       struct Trail_Element *element;
1783       element = trail->trail_head;
1784       for (k = 0; k < trail->trail_length; k++)
1785       {
1786         print_peer = element->peer;
1787         FPRINTF (stderr,_("\nSUPU %s, %s, %d,trail[%d] = %s "),__FILE__, __func__,__LINE__,k, GNUNET_i2s(&print_peer));
1788         element = element->next;
1789       }
1790     }
1791     #endif
1792   }
1793 }
1794 #endif
1795
1796 /**
1797  * Select the closest peer among two peers (which should not be same)
1798  * with respect to value and finger_table_index
1799  * NOTE: peer1 != peer2
1800  * @param peer1 First peer
1801  * @param peer2 Second peer
1802  * @param value Value relative to which we find the closest
1803  * @param is_predecessor Is value a predecessor or any other finger.
1804  * @return Closest peer among two peers.
1805  */
1806 const static struct GNUNET_PeerIdentity *
1807 select_closest_peer (const struct GNUNET_PeerIdentity *peer1,
1808                      const struct GNUNET_PeerIdentity *peer2,
1809                      uint64_t value,
1810                      unsigned int is_predecessor)
1811 {
1812   if (1 == is_predecessor)
1813     return select_closest_predecessor (peer1, peer2, value);
1814
1815   return select_closest_finger (peer1, peer2, value);
1816 }
1817
1818
1819 /**
1820  * Iterate over the list of all the trails of a finger. In case the first
1821  * friend to reach the finger has reached trail threshold or is congested,
1822  * then don't select it. In case there multiple available good trails to reach
1823  * to Finger, choose the one with shortest trail length.
1824  * Note: We use length as parameter. But we can use any other suitable parameter
1825  * also.
1826  * @param finger Finger
1827  * @return struct Selected_Finger_Trail which contains the first friend , trail id
1828  * and trail length. NULL in case none of the trails are free.
1829  */
1830 static struct Selected_Finger_Trail *
1831 select_finger_trail (struct FingerInfo *finger)
1832 {
1833   struct FriendInfo *friend;
1834   struct Trail *iterator;
1835   struct Selected_Finger_Trail *finger_trail;
1836   unsigned int i;
1837   unsigned int flag = 0;
1838   unsigned int j = 0;
1839
1840   finger_trail = GNUNET_new (struct Selected_Finger_Trail);
1841   GNUNET_assert (finger->trails_count > 0);
1842
1843   for (i = 0; i < finger->trails_count; i++)
1844   {
1845     iterator = &finger->trail_list[i];
1846
1847     /* No trail stored at this index. */
1848     if (GNUNET_NO == iterator->is_present)
1849       continue;
1850
1851     GNUNET_assert (NULL !=
1852                   (friend =
1853                    GNUNET_CONTAINER_multipeermap_get (friend_peermap,
1854                                                       &iterator->trail_head->peer)));
1855
1856     /* First friend to reach trail is not free. */
1857     if (GNUNET_YES == is_friend_congested (friend))
1858     {
1859       j++;
1860       continue;
1861     }
1862
1863     if (!flag)
1864     {
1865       flag = 1;
1866       finger_trail->trail_length = iterator->trail_length;
1867       finger_trail->friend = *friend;
1868       finger_trail->trail_id = iterator->trail_id;
1869     }
1870     else if (finger_trail->trail_length > iterator->trail_length)
1871     {
1872       finger_trail->friend = *friend;
1873       finger_trail->trail_id = iterator->trail_id;
1874       finger_trail->trail_length = iterator->trail_length;
1875     }
1876   }
1877
1878   /* All the first friend in all the trails to reach to finger are either
1879    congested or have crossed trail threshold. */
1880   if (j == finger->trails_count)
1881     return NULL;
1882
1883   return finger_trail;
1884 }
1885
1886
1887 /**
1888  * Compare FINGER entry with current successor. If finger's first friend of all
1889  * its trail is not congested and  has not crossed trail threshold, then check
1890  * if finger peer identity is closer to final_destination_finger_value than
1891  * current_successor. If yes then update current_successor.
1892  * @param current_successor[in/out]
1893  * @return
1894  */
1895 static void
1896 compare_finger_and_current_successor (struct Closest_Peer *current_closest_peer)
1897 {
1898   struct FingerInfo *finger;
1899   const struct GNUNET_PeerIdentity *closest_peer;
1900   struct Selected_Finger_Trail *finger_trail;
1901   int i;
1902
1903   /* Iterate over finger table. */
1904   for (i = 0; i < MAX_FINGERS; i++)
1905   {
1906     finger = &finger_table[i];
1907
1908     if (GNUNET_NO == finger->is_present)
1909       continue;
1910
1911     /* FIXME write correct comment here */
1912     if (0 == GNUNET_CRYPTO_cmp_peer_identity (&finger->finger_identity,
1913                                               &current_closest_peer->best_known_destination))
1914       continue;
1915
1916     /* If I am my own finger, then ignore this finger. */
1917     if (0 == GNUNET_CRYPTO_cmp_peer_identity (&finger->finger_identity,
1918                                               &my_identity))
1919     {
1920       /* FIXME: I think a peer should not select itself as its own identity ever.
1921        But it does select. Find out why??*/
1922       //GNUNET_break (0);
1923       //continue;
1924       return;
1925     }
1926
1927     /* If finger is a friend, then do nothing. As we have already checked
1928      * for each friend in compare_friend_and_current_successor(). */
1929     if (NULL != (GNUNET_CONTAINER_multipeermap_get (friend_peermap,
1930                                                     &finger->finger_identity)))
1931     {
1932       continue;
1933     }
1934
1935     closest_peer = select_closest_peer (&finger->finger_identity,
1936                                         &current_closest_peer->best_known_destination,
1937                                         current_closest_peer->destination_finger_value,
1938                                         current_closest_peer->is_predecessor);
1939
1940     if (&finger->finger_identity == closest_peer)
1941     {
1942       /* Choose one of the trail to reach to finger. */
1943       finger_trail = select_finger_trail (finger);
1944
1945       /* In case no trail found, ignore this finger. */
1946       if (NULL == finger_trail)
1947         continue;
1948
1949       current_closest_peer->best_known_destination = finger->finger_identity;
1950       current_closest_peer->next_hop = finger_trail->friend.id;
1951       current_closest_peer->trail_id = finger_trail->trail_id;
1952       GNUNET_free(finger_trail);
1953     }
1954     continue;
1955   }
1956 }
1957
1958
1959 /**
1960  * Compare friend entry with current successor.
1961  * If friend identity and current_successor is same, then do nothing.
1962  * If friend is not congested and has not crossed trail threshold, then check
1963  * if friend peer identity is closer to final_destination_finger_value than
1964  * current_successor. If yes then update current_successor.
1965  * @param cls closure
1966  * @param key current public key
1967  * @param value struct Closest_Peer
1968  * @return #GNUNET_YES if we should continue to iterate,
1969  *         #GNUNET_NO if not.
1970  */
1971 static int
1972 compare_friend_and_current_closest_peer (void *cls,
1973                                          const struct GNUNET_PeerIdentity *key,
1974                                          void *value)
1975 {
1976   struct FriendInfo *friend = value;
1977   struct Closest_Peer *current_closest_peer = cls;
1978   const struct GNUNET_PeerIdentity *closest_peer;
1979
1980   /* Friend is either congested or has crossed threshold. */
1981   if (GNUNET_YES == is_friend_congested (friend))
1982     return GNUNET_YES;
1983
1984   /* If current_closest_peer and friend identity are same, then do nothing.*/
1985   if (0 == GNUNET_CRYPTO_cmp_peer_identity (&friend->id,
1986                                             &current_closest_peer->best_known_destination))
1987   {
1988     GNUNET_break (0);
1989     return GNUNET_YES;
1990   }
1991
1992   closest_peer = select_closest_peer (&friend->id,
1993                                       &current_closest_peer->best_known_destination,
1994                                       current_closest_peer->destination_finger_value,
1995                                       current_closest_peer->is_predecessor);
1996
1997   /* Is friend the closest successor? */
1998   if (&friend->id == closest_peer)
1999   {
2000     current_closest_peer->best_known_destination = friend->id;
2001     current_closest_peer->next_hop = friend->id;
2002   }
2003
2004   return GNUNET_YES;
2005 }
2006
2007
2008 /**
2009  * Initialize current_successor to my_identity.
2010  * @param my_identity My peer identity
2011  * @return Updated closest_peer
2012  */
2013 static struct Closest_Peer
2014 init_current_successor (struct GNUNET_PeerIdentity my_identity,
2015                         uint64_t destination_finger_value,
2016                         unsigned int is_predecessor)
2017 {
2018   struct Closest_Peer current_closest_peer;
2019
2020   memset (&current_closest_peer.trail_id, 0, sizeof(struct GNUNET_HashCode));
2021   current_closest_peer.destination_finger_value = destination_finger_value;
2022   current_closest_peer.is_predecessor = is_predecessor;
2023   current_closest_peer.next_hop = my_identity;
2024   current_closest_peer.best_known_destination = my_identity;
2025
2026   return current_closest_peer;
2027 }
2028
2029
2030 /**
2031  * FIXME: at the moment, there is not 100% get and put in case of non-malicious
2032  * peer. It could be because of the logic we wrote here. Verify if its correct.
2033  * If not then return immediate_successor.
2034  *
2035  * Find the successor for destination_finger_value among my_identity, my
2036  * friends and my fingers. Don't consider friends or fingers which are either
2037  * congested or have crossed the threshold.
2038  * NOTE: In case a friend is also a finger, then it is always chosen as friend
2039  * not a finger.
2040  * @param destination_finger_value Peer closest to this value will be the next successor.
2041  * @param is_predecessor Are we looking for predecessor or finger?
2042  * @return Successor It is never NULL, in case none of friend or finger is closest,
2043  *                   then we return my_identity.
2044  */
2045 static struct Closest_Peer
2046 find_successor (uint64_t destination_finger_value,
2047                 unsigned int is_predecessor)
2048 {
2049   struct Closest_Peer current_closest_peer;
2050
2051    /* Initialize current_successor to my_identity. */
2052   current_closest_peer = init_current_successor (my_identity,
2053                                                  destination_finger_value,
2054                                                  is_predecessor);
2055
2056   /* Compare each friend entry with current_successor and update current_successor
2057    * with friend if its closest. */
2058   GNUNET_assert
2059           (GNUNET_SYSERR !=
2060            GNUNET_CONTAINER_multipeermap_iterate (friend_peermap,
2061                                                   &compare_friend_and_current_closest_peer,
2062                                                   &current_closest_peer));
2063
2064   /* Compare each finger entry with current_successor and update current_successor
2065    * with finger if its closest. */
2066   compare_finger_and_current_successor (&current_closest_peer);
2067
2068   return current_closest_peer;
2069 }
2070
2071
2072 /**
2073  * Construct a Put message and send it to target_peer.
2074  * @param key Key for the content
2075  * @param block_type Type of the block
2076  * @param options Routing options
2077  * @param desired_replication_level Desired replication count
2078  * @param best_known_dest Peer to which this message should reach eventually,
2079  *                        as it is best known destination to me.
2080  * @param intermediate_trail_id Trail id in case
2081  * @param target_peer Peer to which this message will be forwarded.
2082  * @param hop_count Number of hops traversed so far.
2083  * @param put_path_length Total number of peers in @a put_path
2084  * @param put_path Number of peers traversed so far
2085  * @param expiration_time When does the content expire
2086  * @param data Content to store
2087  * @param data_size Size of content @a data in bytes
2088  */
2089 void
2090 GDS_NEIGHBOURS_send_put (const struct GNUNET_HashCode *key,
2091                          enum GNUNET_BLOCK_Type block_type,
2092                                            enum GNUNET_DHT_RouteOption options,
2093                                            uint32_t desired_replication_level,
2094                                            struct GNUNET_PeerIdentity best_known_dest,
2095                                            struct GNUNET_HashCode intermediate_trail_id,
2096                                            struct GNUNET_PeerIdentity *target_peer,
2097                          uint32_t hop_count,
2098                          uint32_t put_path_length,
2099                          struct GNUNET_PeerIdentity *put_path,
2100                          struct GNUNET_TIME_Absolute expiration_time,
2101                          const void *data, size_t data_size)
2102 {
2103   struct PeerPutMessage *ppm;
2104   struct P2PPendingMessage *pending;
2105   struct FriendInfo *target_friend;
2106   struct GNUNET_PeerIdentity *pp;
2107   struct GNUNET_PeerIdentity next_hop;
2108
2109   size_t msize;
2110
2111   msize = put_path_length * sizeof (struct GNUNET_PeerIdentity) + data_size +
2112           sizeof (struct PeerPutMessage);
2113
2114   if (msize >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
2115   {
2116     put_path_length = 0;
2117     msize = data_size + sizeof (struct PeerPutMessage);
2118   }
2119
2120   if (msize >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
2121   {
2122     GNUNET_break (0);
2123     return;
2124   }
2125
2126   /* This is the first call made from clients file. So, we should search for the
2127      target_friend. */
2128   if (NULL == target_peer)
2129   {
2130     uint64_t key_value;
2131     struct Closest_Peer successor;
2132
2133     memcpy (&key_value, key, sizeof (uint64_t));
2134     key_value = GNUNET_ntohll (key_value);
2135
2136     successor = find_successor (key_value, GDS_FINGER_TYPE_NON_PREDECESSOR);
2137     best_known_dest = successor.best_known_destination;
2138     next_hop = successor.next_hop;
2139     intermediate_trail_id = successor.trail_id;
2140
2141     if (0 == GNUNET_CRYPTO_cmp_peer_identity (&best_known_dest, &my_identity))
2142     {
2143       /* I am the destination. */
2144       GDS_DATACACHE_handle_put (expiration_time, key, 0, NULL,
2145                                 block_type,data_size,data);
2146       return;
2147     }
2148     else
2149       GNUNET_assert (NULL !=
2150                     (target_friend =
2151                      GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop)));
2152   }
2153   else
2154   {
2155     GNUNET_assert (NULL !=
2156                    (target_friend =
2157                    GNUNET_CONTAINER_multipeermap_get (friend_peermap, target_peer)));
2158   }
2159
2160   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
2161   pending->timeout = expiration_time;
2162   ppm = (struct PeerPutMessage *) &pending[1];
2163   pending->msg = &ppm->header;
2164   ppm->header.size = htons (msize);
2165   ppm->header.type = htons (GNUNET_MESSAGE_TYPE_XDHT_P2P_PUT);
2166   ppm->options = htonl (options);
2167   ppm->block_type = htonl (block_type);
2168   ppm->hop_count = htonl (hop_count + 1);
2169   ppm->desired_replication_level = htonl (desired_replication_level);
2170   ppm->put_path_length = htonl (put_path_length);
2171   ppm->expiration_time = GNUNET_TIME_absolute_hton (expiration_time);
2172   ppm->best_known_destination = best_known_dest;
2173   ppm->key = *key;
2174
2175   pp = (struct GNUNET_PeerIdentity *) &ppm[1];
2176   if (put_path_length != 0)
2177   {
2178     memcpy (pp, put_path,
2179             sizeof (struct GNUNET_PeerIdentity) * put_path_length);
2180   }
2181   memcpy (&pp[put_path_length], data, data_size);
2182   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
2183   target_friend->pending_count++;
2184   process_friend_queue (target_friend);
2185 }
2186
2187
2188 /**
2189  * Construct a Get message and send it to target_peer.
2190  * @param key Key for the content
2191  * @param block_type Type of the block
2192  * @param options Routing options
2193  * @param desired_replication_level Desired replication count
2194  * @param best_known_dest Peer which should get this message. Same as target peer
2195  *                        if best_known_dest is a friend else its a finger.
2196  * @param intermediate_trail_id  Trail id to reach to @a best_known_dest
2197  *                              in case it is a finger else set to 0.
2198  * @param target_peer Peer to which this message will be forwarded.
2199  * @param hop_count Number of hops traversed so far.
2200  * @param data Content to store
2201  * @param data_size Size of content @a data in bytes
2202  * @param get_path_length Total number of peers in @a get_path
2203  * @param get_path Number of peers traversed so far
2204  */
2205 void
2206 GDS_NEIGHBOURS_send_get (const struct GNUNET_HashCode *key,
2207                          enum GNUNET_BLOCK_Type block_type,
2208                          enum GNUNET_DHT_RouteOption options,
2209                          uint32_t desired_replication_level,
2210                          struct GNUNET_PeerIdentity best_known_dest,
2211                          struct GNUNET_HashCode intermediate_trail_id,
2212                          struct GNUNET_PeerIdentity *target_peer,
2213                          uint32_t hop_count,
2214                          uint32_t get_path_length,
2215                          struct GNUNET_PeerIdentity *get_path)
2216 {
2217   struct PeerGetMessage *pgm;
2218   struct P2PPendingMessage *pending;
2219   struct FriendInfo *target_friend;
2220   struct GNUNET_PeerIdentity *gp;
2221   size_t msize;
2222
2223   msize = sizeof (struct PeerGetMessage) +
2224           (get_path_length * sizeof (struct GNUNET_PeerIdentity));
2225   
2226   //GNUNET_SERVER_MAX_MESSAGE_SIZE
2227   /* FIXME:TODO:URGENTHere you can try to optimize it a bit. In case the get path contains you
2228    or your friend then shorten the path. */
2229   /* In this case we don't make get_path_length = 0, as we need get path to
2230    * return the message back to querying client. */
2231   if (msize >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
2232   {
2233     GNUNET_break (0);
2234     return;
2235   }
2236
2237   /* This is the first time we got request from our own client file. */
2238   if (NULL == target_peer)
2239   {
2240     uint64_t key_value;
2241     struct Closest_Peer successor;
2242
2243     memcpy (&key_value, key, sizeof (uint64_t));
2244     key_value = GNUNET_ntohll (key_value);
2245     successor = find_successor (key_value, GDS_FINGER_TYPE_NON_PREDECESSOR);
2246
2247     best_known_dest = successor.best_known_destination;
2248     intermediate_trail_id = successor.trail_id;
2249
2250     /* I am the destination. I have the data. */
2251     if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity,
2252                                               &best_known_dest))
2253     {
2254       GDS_DATACACHE_handle_get (key,block_type, NULL, 0,
2255                                 NULL, 0, 1, &my_identity, NULL,&my_identity);
2256
2257       return;
2258     }
2259     else
2260     {
2261       GNUNET_assert (NULL !=
2262                     (target_friend =
2263                      GNUNET_CONTAINER_multipeermap_get (friend_peermap,
2264                                                         &successor.next_hop)));
2265     }
2266
2267   }
2268   else
2269   {
2270     GNUNET_assert (NULL !=
2271                   (target_friend =
2272                    GNUNET_CONTAINER_multipeermap_get (friend_peermap, target_peer))); //FIXME: assertion fails.
2273   }
2274
2275   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
2276   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
2277   pending->importance = 0;    /* FIXME */
2278   pgm = (struct PeerGetMessage *) &pending[1];
2279   pending->msg = &pgm->header;
2280   pgm->header.size = htons (msize);
2281   pgm->header.type = htons (GNUNET_MESSAGE_TYPE_XDHT_P2P_GET);
2282   pgm->get_path_length = htonl (get_path_length);
2283   pgm->best_known_destination = best_known_dest;
2284   pgm->key = *key;
2285   pgm->intermediate_trail_id = intermediate_trail_id;
2286   pgm->hop_count = htonl (hop_count + 1);
2287   gp = (struct GNUNET_PeerIdentity *) &pgm[1];
2288
2289   if (get_path_length != 0)
2290   {
2291     memcpy (gp, get_path, get_path_length * sizeof (struct GNUNET_PeerIdentity));
2292   }
2293
2294   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
2295   target_friend->pending_count++;
2296   process_friend_queue (target_friend);
2297 }
2298
2299
2300 /**
2301  * Send the get result to requesting client.
2302  * @param key Key of the requested data.
2303  * @param type Block type
2304  * @param target_peer Next peer to forward the message to.
2305  * @param source_peer Peer which has the data for the key.
2306  * @param put_path_length Number of peers in @a put_path
2307  * @param put_path Path taken to put the data at its stored location.
2308  * @param get_path_length Number of peers in @a get_path
2309  * @param get_path Path taken to reach to the location of the key.
2310  * @param expiration When will this result expire?
2311  * @param data Payload to store
2312  * @param data_size Size of the @a data
2313  */
2314 void
2315 GDS_NEIGHBOURS_send_get_result (const struct GNUNET_HashCode *key,
2316                                 enum GNUNET_BLOCK_Type type,
2317                                 const struct GNUNET_PeerIdentity *target_peer,
2318                                 const struct GNUNET_PeerIdentity *source_peer,
2319                                 unsigned int put_path_length,
2320                                 const struct GNUNET_PeerIdentity *put_path,
2321                                 unsigned int get_path_length,
2322                                 const struct GNUNET_PeerIdentity *get_path,
2323                                 struct GNUNET_TIME_Absolute expiration,
2324                                 const void *data, size_t data_size)
2325 {
2326   struct PeerGetResultMessage *get_result;
2327   struct GNUNET_PeerIdentity *paths;
2328   struct P2PPendingMessage *pending;
2329   struct FriendInfo *target_friend;
2330   int current_path_index;
2331   size_t msize;
2332
2333   msize = (put_path_length + get_path_length )* sizeof (struct GNUNET_PeerIdentity) +
2334           data_size +
2335           sizeof (struct PeerGetResultMessage);
2336
2337   if (msize >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
2338   {
2339     put_path_length = 0;
2340     msize = msize - put_path_length;
2341     return;
2342   }
2343
2344   if (msize >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
2345   {
2346     GNUNET_break(0);
2347     return;
2348   }
2349   
2350   current_path_index = 0;
2351   if(get_path_length > 0)
2352   {
2353     current_path_index = search_my_index(get_path, get_path_length);
2354     if (-1 == current_path_index)
2355     {
2356       GNUNET_break (0);
2357       return;
2358     }
2359   }
2360   if (0 == current_path_index)
2361   {
2362     GDS_CLIENTS_handle_reply (expiration, key, get_path_length,
2363                               get_path, put_path_length,
2364                               put_path, type, data_size, data);
2365     return;
2366   }
2367
2368   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
2369   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
2370   pending->importance = 0;
2371   get_result = (struct PeerGetResultMessage *)&pending[1];
2372   pending->msg = &get_result->header;
2373   get_result->header.size = htons (msize);
2374   get_result->header.type = htons (GNUNET_MESSAGE_TYPE_XDHT_P2P_GET_RESULT);
2375   get_result->key = *key;
2376   get_result->querying_peer = *source_peer;
2377   get_result->expiration_time = expiration;
2378   get_result->get_path_length = htonl (get_path_length);
2379   get_result->put_path_length = htonl (put_path_length);
2380   paths = (struct GNUNET_PeerIdentity *)&get_result[1];
2381   memcpy (paths, put_path,
2382           put_path_length * sizeof (struct GNUNET_PeerIdentity));
2383   memcpy (&paths[put_path_length], get_path,
2384           get_path_length * sizeof (struct GNUNET_PeerIdentity));
2385   memcpy (&paths[put_path_length + get_path_length], data, data_size);
2386
2387   GNUNET_assert (NULL !=
2388                 (target_friend =
2389                  GNUNET_CONTAINER_multipeermap_get (friend_peermap,
2390                                                     &get_path[current_path_index - 1])));
2391   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
2392   target_friend->pending_count++;
2393   process_friend_queue (target_friend);
2394 }
2395
2396
2397 /**
2398  * Randomly choose one of your friends (which is not congested and have not crossed
2399  * trail threshold) from the friend_peermap
2400  * @return Friend Randomly chosen friend.
2401  *         NULL in case friend peermap is empty, or all the friends are either
2402  *              congested or have crossed trail threshold.
2403  */
2404 static struct FriendInfo *
2405 select_random_friend ()
2406 {
2407   unsigned int current_size;
2408   uint32_t index;
2409   unsigned int j = 0;
2410   struct GNUNET_CONTAINER_MultiPeerMapIterator *iter;
2411   struct GNUNET_PeerIdentity key_ret;
2412   struct FriendInfo *friend;
2413
2414   current_size = GNUNET_CONTAINER_multipeermap_size (friend_peermap);
2415
2416   /* No friends.*/
2417   if (0 == current_size)
2418     return NULL;
2419
2420   index = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, current_size);
2421   iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap);
2422
2423   /* Iterate till you don't reach to index. */
2424   for (j = 0; j < index ; j++)
2425     GNUNET_assert (GNUNET_YES ==
2426                    GNUNET_CONTAINER_multipeermap_iterator_next (iter, NULL, NULL));
2427   do
2428   {
2429     /* Reset the index in friend peermap to 0 as we reached to the end. */
2430     if (j == current_size)
2431     {
2432       j = 0;
2433       GNUNET_CONTAINER_multipeermap_iterator_destroy (iter);
2434       iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap);
2435
2436     }
2437
2438     /* Get the friend stored at the index, j*/
2439     GNUNET_assert (GNUNET_YES ==
2440                    GNUNET_CONTAINER_multipeermap_iterator_next (iter,
2441                                                                 &key_ret,
2442                                                                 (const void **)&friend));
2443
2444     /* This friend is not congested and has not crossed trail threshold. */
2445     if ((TRAILS_THROUGH_FRIEND_THRESHOLD > friend->trails_count) &&
2446         (0 == GNUNET_TIME_absolute_get_remaining (friend->congestion_timestamp).rel_value_us))
2447     {
2448       break;
2449     }
2450     friend = NULL;
2451     j++;
2452   } while (j != index);
2453
2454   GNUNET_CONTAINER_multipeermap_iterator_destroy (iter);
2455   return friend;
2456 }
2457
2458
2459 /**
2460  * Compute 64 bit value of finger_identity corresponding to a finger index using
2461  * chord formula.
2462  * For all fingers, n.finger[i] = n + pow (2,i),
2463  * For predecessor, n.finger[PREDECESSOR_FINGER_ID] = n - 1, where
2464  * n = my_identity, i = finger_index, n.finger[i] = 64 bit finger value
2465  * @param finger_index Index corresponding to which we calculate 64 bit value.
2466  * @return 64 bit value.
2467  */
2468 static uint64_t
2469 compute_finger_identity_value (unsigned int finger_index)
2470 {
2471   uint64_t my_id64;
2472
2473   memcpy (&my_id64, &my_identity, sizeof (uint64_t));
2474   my_id64 = GNUNET_ntohll (my_id64);
2475
2476   /* Are we looking for immediate predecessor? */
2477   if (PREDECESSOR_FINGER_ID == finger_index)
2478     return (my_id64 - 1);
2479   else
2480   {
2481     uint64_t add = (uint64_t)1 << finger_index;
2482     return (my_id64 + add);
2483   }
2484 }
2485
2486 static struct GNUNET_TIME_Relative next_send_time;
2487
2488 /*
2489  * Choose a random friend. Calculate the next finger identity to search,from
2490  * current_search_finger_index. Start looking for the trail to reach to
2491  * finger identity through this random friend.
2492  *
2493  * @param cls closure for this task
2494  * @param tc the context under which the task is running
2495  */
2496 static void
2497 send_find_finger_trail_message (void *cls,
2498                                 const struct GNUNET_SCHEDULER_TaskContext *tc)
2499 {
2500   struct FriendInfo *target_friend;
2501   //struct GNUNET_TIME_Relative next_send_time;
2502   struct GNUNET_HashCode trail_id;
2503   struct GNUNET_HashCode intermediate_trail_id;
2504   unsigned int is_predecessor;
2505   uint64_t finger_id_value;
2506   
2507   /* Schedule another send_find_finger_trail_message task. */
2508   find_finger_trail_task =
2509       GNUNET_SCHEDULER_add_delayed (next_send_time,
2510                                     &send_find_finger_trail_message,
2511                                     NULL);
2512
2513    /* No space in my routing table. (Source and destination peers also store entries
2514    * in their routing table).  */
2515   if (GNUNET_YES == GDS_ROUTING_threshold_reached())
2516     return;
2517
2518
2519   target_friend = select_random_friend ();
2520   if (NULL == target_friend)
2521   {
2522     return;
2523   }
2524
2525   finger_id_value = compute_finger_identity_value (current_search_finger_index);
2526
2527   if (PREDECESSOR_FINGER_ID == current_search_finger_index)
2528     is_predecessor = 1;
2529   else
2530     is_predecessor = 0;
2531
2532   /* Generate a unique trail id for trail we are trying to setup. */
2533   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG,
2534                               &trail_id, sizeof (trail_id));
2535   memset(&intermediate_trail_id, 0, sizeof (struct GNUNET_HashCode));
2536
2537   GDS_NEIGHBOURS_send_trail_setup (my_identity, finger_id_value,
2538                                    target_friend->id, target_friend, 0, NULL,
2539                                    is_predecessor, trail_id,
2540                                    intermediate_trail_id);
2541 }
2542
2543
2544 /**
2545  * In case there are already maximum number of possible trails to reach to a
2546  * finger, then check if the new trail's length is lesser than any of the
2547  * existing trails.
2548  * If yes then replace that old trail by new trail.
2549  *
2550  * Note: Here we are taking length as a parameter to choose the best possible
2551  * trail, but there could be other parameters also like:
2552  * 1. duration of existence of a trail - older the better.
2553  * 2. if the new trail is completely disjoint than the
2554  *    other trails, then may be choosing it is better.
2555  *
2556  * @param existing_finger
2557  * @param new_finger_trail
2558  * @param new_finger_trail_length
2559  * @param new_finger_trail_id
2560  */
2561 static void
2562 select_and_replace_trail (struct FingerInfo *existing_finger,
2563                           const struct GNUNET_PeerIdentity *new_trail,
2564                           unsigned int new_trail_length,
2565                           struct GNUNET_HashCode new_trail_id)
2566 {
2567   struct Trail *trail_list_iterator;
2568   unsigned int largest_trail_length;
2569   unsigned int largest_trail_index;
2570   struct Trail_Element *trail_element;
2571   unsigned int i;
2572
2573   largest_trail_length = new_trail_length;
2574   largest_trail_index = MAXIMUM_TRAILS_PER_FINGER + 1;
2575
2576   GNUNET_assert (MAXIMUM_TRAILS_PER_FINGER == existing_finger->trails_count);
2577
2578   for (i = 0; i < existing_finger->trails_count; i++)
2579   {
2580     trail_list_iterator = &existing_finger->trail_list[i];
2581     if (trail_list_iterator->trail_length > largest_trail_length)
2582     {
2583       largest_trail_length = trail_list_iterator->trail_length;
2584       largest_trail_index = i;
2585     }
2586   }
2587
2588   /* New trail is not better than existing ones. Send trail teardown. */
2589   if (largest_trail_index == (MAXIMUM_TRAILS_PER_FINGER + 1))
2590   {
2591     struct GNUNET_PeerIdentity next_hop;
2592
2593     memcpy (&next_hop, &new_trail[0], sizeof(struct GNUNET_PeerIdentity));
2594     GDS_ROUTING_remove_trail (new_trail_id);
2595     GDS_NEIGHBOURS_send_trail_teardown (new_trail_id,
2596                                         GDS_ROUTING_SRC_TO_DEST,
2597                                         next_hop);
2598     return;
2599   }
2600
2601   /* Send trail teardown message across the replaced trail. */
2602   struct Trail *replace_trail = &existing_finger->trail_list[largest_trail_index];
2603   existing_finger->trail_list[largest_trail_index].is_present = GNUNET_NO;
2604   GNUNET_assert (GNUNET_YES == GDS_ROUTING_remove_trail (replace_trail->trail_id));
2605   GDS_NEIGHBOURS_send_trail_teardown (replace_trail->trail_id,
2606                                       GDS_ROUTING_SRC_TO_DEST,
2607                                       replace_trail->trail_head->peer);
2608   /* Free the trail. */
2609   while (NULL != (trail_element = replace_trail->trail_head))
2610   {
2611     GNUNET_CONTAINER_DLL_remove (replace_trail->trail_head,
2612                                  replace_trail->trail_tail, trail_element);
2613     GNUNET_free_non_null (trail_element);
2614   }
2615
2616   /* Add new trial at that location. */
2617   replace_trail->is_present = GNUNET_YES;
2618   replace_trail->trail_length = new_trail_length;
2619   replace_trail->trail_id = new_trail_id;
2620   //FIXME: Do we need to add pointers for head and tail.
2621   i = 0;
2622   while (i < new_trail_length)
2623   {
2624     struct Trail_Element *element = GNUNET_new (struct Trail_Element);
2625     element->peer = new_trail[i];
2626
2627     GNUNET_CONTAINER_DLL_insert_tail (replace_trail->trail_head,
2628                                       replace_trail->trail_tail,
2629                                       element);
2630   }
2631 }
2632
2633
2634 /**
2635  * Check if the new trail to reach to finger is unique or do we already have
2636  * such a trail present for finger.
2637  * @param existing_finger Finger identity
2638  * @param new_trail New trail to reach @a existing_finger
2639  * @param trail_length Total number of peers in new_trail.
2640  * @return #GNUNET_YES if the new trail is unique
2641  *         #GNUNET_NO if same trail is already present.
2642  */
2643 static int
2644 is_new_trail_unique (struct FingerInfo *existing_finger,
2645                      const struct GNUNET_PeerIdentity *new_trail,
2646                      unsigned int trail_length)
2647 {
2648   struct Trail *trail_list_iterator;
2649   struct Trail_Element *trail_element;
2650   int i;
2651   int j;
2652   int trail_unique = GNUNET_NO;
2653
2654   GNUNET_assert (existing_finger->trails_count > 0);
2655
2656   /* Iterate over list of trails. */
2657   for (i = 0; i < existing_finger->trails_count; i++)
2658   {
2659     trail_list_iterator = &existing_finger->trail_list[i];
2660     GNUNET_assert (GNUNET_YES == trail_list_iterator->is_present);
2661
2662     /* New trail and existing trail length are not same. */
2663     if (trail_list_iterator->trail_length != trail_length)
2664     {
2665       trail_unique = GNUNET_YES;
2666       continue;
2667     }
2668
2669     trail_element = trail_list_iterator->trail_head;
2670     for (j = 0; j < trail_list_iterator->trail_length; j++)
2671     {
2672       if (0 != GNUNET_CRYPTO_cmp_peer_identity (&new_trail[j],
2673                                                 &trail_element->peer))
2674       {
2675         trail_unique = GNUNET_YES;
2676         continue;
2677       }
2678       trail_element = trail_element->next;
2679     }
2680
2681     trail_unique = GNUNET_NO;
2682   }
2683
2684   return trail_unique;
2685 }
2686
2687
2688 /**
2689  * Add a new trail to existing finger. This function is called only when finger
2690  * is not my own identity or a friend.
2691  * @param existing_finger Finger
2692  * @param new_finger_trail New trail from me to finger, NOT including endpoints
2693  * @param new_finger_trail_length Total number of peers in @a new_finger_trail
2694  * @param new_finger_trail_id Unique identifier of the trail.
2695  */
2696 static void
2697 add_new_trail (struct FingerInfo *existing_finger,
2698                const struct GNUNET_PeerIdentity *new_trail,
2699                unsigned int new_trail_length,
2700                struct GNUNET_HashCode new_trail_id)
2701 {
2702   struct Trail *trail_list_iterator;
2703   struct FriendInfo *first_friend;
2704   int i;
2705
2706   if (GNUNET_NO == is_new_trail_unique (existing_finger, new_trail,
2707                                         new_trail_length))
2708   {
2709     return;
2710   }
2711
2712   trail_list_iterator = &existing_finger->trail_list[existing_finger->trails_count];
2713   GNUNET_assert (GNUNET_NO == trail_list_iterator->is_present);
2714   trail_list_iterator->trail_id = new_trail_id;
2715   trail_list_iterator->trail_length = new_trail_length;
2716   existing_finger->trails_count++;
2717   trail_list_iterator->is_present = GNUNET_YES;
2718
2719   GNUNET_assert (NULL == (GNUNET_CONTAINER_multipeermap_get (friend_peermap,
2720                                                              &existing_finger->finger_identity)));
2721   /* If finger is a friend then we never call this function. */
2722   GNUNET_assert (new_trail_length > 0);
2723
2724   first_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap,
2725                                                     &new_trail[0]);
2726   first_friend->trails_count++;
2727
2728   for (i = 0; i < new_trail_length; i++)
2729   {
2730     struct Trail_Element *element;
2731
2732     element = GNUNET_new (struct Trail_Element);
2733     element->peer = new_trail[i];
2734     GNUNET_CONTAINER_DLL_insert_tail (trail_list_iterator->trail_head,
2735                                       trail_list_iterator->trail_tail,
2736                                       element);
2737   }
2738   /* Do we need to add trail head and trail tail in the trail list itearator.*/
2739
2740 }
2741
2742
2743 /**
2744  * FIXME Check if this function is called for opposite direction if yes then
2745  * take it as parameter.
2746  * Get the next hop to send trail teardown message from routing table and
2747  * then delete the entry from routing table. Send trail teardown message for a
2748  * specific trail of a finger.
2749  * @param finger Finger whose trail is to be removed.
2750  * @param trail List of peers in trail from me to a finger, NOT including
2751  *              endpoints.
2752  */
2753 static void
2754 send_trail_teardown (struct FingerInfo *finger,
2755                      struct Trail *trail)
2756 {
2757   struct FriendInfo *friend;
2758   struct GNUNET_PeerIdentity *next_hop;
2759
2760   next_hop = GDS_ROUTING_get_next_hop (trail->trail_id,
2761                                        GDS_ROUTING_SRC_TO_DEST);
2762   
2763   if (NULL == next_hop)
2764   {
2765     GNUNET_break(0);
2766     return;
2767   }
2768   GNUNET_assert (0 != GNUNET_CRYPTO_cmp_peer_identity (&finger->finger_identity,
2769                                                        &my_identity));
2770
2771   GNUNET_assert (trail->is_present == GNUNET_YES);
2772
2773   /* Finger is not a friend. */
2774   if (trail->trail_length > 0)
2775   {
2776     GNUNET_assert (NULL != (friend =
2777                    GNUNET_CONTAINER_multipeermap_get (friend_peermap,
2778                                                       &trail->trail_head->peer)));
2779   }
2780   else
2781   {
2782     GNUNET_assert (NULL != (friend =
2783                    GNUNET_CONTAINER_multipeermap_get (friend_peermap,
2784                                                       &finger->finger_identity)));
2785   }
2786
2787   GNUNET_assert (0 == GNUNET_CRYPTO_cmp_peer_identity (next_hop, &friend->id)); //Fixme: assertion fails.
2788   GNUNET_assert (GNUNET_YES == GDS_ROUTING_remove_trail (trail->trail_id));
2789   friend->trails_count--;
2790   GDS_NEIGHBOURS_send_trail_teardown (trail->trail_id,
2791                                       GDS_ROUTING_SRC_TO_DEST,
2792                                       friend->id);
2793 }
2794
2795
2796 /**
2797  * Send trail teardown message across all the trails to reach to finger.
2798  * @param finger Finger whose all the trail should be freed.
2799  */
2800 static void
2801 send_all_finger_trails_teardown (struct FingerInfo *finger)
2802 {
2803   unsigned int i;
2804
2805   for (i = 0; i < finger->trails_count; i++)
2806   {
2807     struct Trail *trail;
2808
2809     trail = &finger->trail_list[i];
2810     GNUNET_assert (trail->is_present == GNUNET_YES);
2811     send_trail_teardown (finger, trail);
2812     trail->is_present = GNUNET_NO;
2813    }
2814 }
2815
2816
2817 /**
2818  * Free a specific trail
2819  * @param trail List of peers to be freed.
2820  */
2821 static void
2822 free_trail (struct Trail *trail)
2823 {
2824   struct Trail_Element *trail_element;
2825
2826   while (NULL != (trail_element = trail->trail_head))
2827   {
2828     GNUNET_CONTAINER_DLL_remove (trail->trail_head,
2829                                  trail->trail_tail,
2830                                  trail_element);
2831     GNUNET_free_non_null (trail_element);
2832   }
2833   trail->trail_head = NULL;
2834   trail->trail_tail = NULL;
2835 }
2836
2837
2838 /**
2839  * Free finger and its trail.
2840  * @param finger Finger to be freed.
2841  */
2842 static void
2843 free_finger (struct FingerInfo *finger, unsigned int finger_table_index)
2844 {
2845   struct Trail *trail;
2846   unsigned int i;
2847
2848   /* Free all the trails to reach to finger */
2849   for (i = 0; i < finger->trails_count; i++)
2850   {
2851     trail = &finger->trail_list[i];
2852     //FIXME: Check if there are any missing entry in this list because of
2853     // how we insert. If not then no need of this check.
2854     if (GNUNET_NO == trail->is_present)
2855       continue;
2856
2857     if (trail->trail_length > 0)
2858     {
2859       free_trail (trail);
2860     }
2861     trail->is_present = GNUNET_NO;
2862   }
2863
2864   finger->is_present = GNUNET_NO;
2865   memset ((void *)&finger_table[finger_table_index], 0, sizeof (finger_table[finger_table_index]));
2866 }
2867
2868
2869 /**
2870  * Add a new entry in finger table at finger_table_index.
2871  * In case I am my own finger, then we don't have a trail. In case of a friend,
2872  * we have a trail with unique id and '0' trail length.
2873  * In case a finger is a friend, then increment the trails count of the friend.
2874  * @param finger_identity Peer Identity of new finger
2875  * @param finger_trail Trail to reach from me to finger (excluding both end points).
2876  * @param finger_trail_length Total number of peers in @a finger_trail.
2877  * @param trail_id Unique identifier of the trail.
2878  * @param finger_table_index Index in finger table.
2879  */
2880 static void
2881 add_new_finger (struct GNUNET_PeerIdentity finger_identity,
2882                 const struct GNUNET_PeerIdentity *finger_trail,
2883                 unsigned int finger_trail_length,
2884                 struct GNUNET_HashCode trail_id,
2885                 unsigned int finger_table_index)
2886 {
2887   struct FingerInfo *new_entry;
2888   struct FriendInfo *first_trail_hop;
2889   struct Trail *trail;
2890   int i = 0;
2891
2892   new_entry = GNUNET_new (struct FingerInfo);
2893   new_entry->finger_identity = finger_identity;
2894   new_entry->finger_table_index = finger_table_index;
2895   new_entry->is_present = GNUNET_YES;
2896
2897   /* If the new entry is my own identity. */
2898   if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity,
2899                                             &finger_identity))
2900   {
2901     new_entry->trails_count = 0;
2902     finger_table[finger_table_index] = *new_entry;
2903     GNUNET_free (new_entry);
2904     return;
2905   }
2906
2907   /* If finger is a friend, then we don't actually have a trail.
2908    *  Just a trail id */
2909   if (NULL != GNUNET_CONTAINER_multipeermap_get (friend_peermap,
2910                                                  &finger_identity))
2911   {
2912     new_entry->trail_list[0].trail_id = trail_id;
2913     new_entry->trails_count = 1;
2914     new_entry->trail_list[0].is_present = GNUNET_YES;
2915     new_entry->trail_list[0].trail_length = 0;
2916     new_entry->trail_list[0].trail_head = NULL;
2917     new_entry->trail_list[0].trail_tail = NULL;
2918     finger_table[finger_table_index] = *new_entry;
2919     GNUNET_assert (NULL !=
2920                   (first_trail_hop =
2921                        GNUNET_CONTAINER_multipeermap_get (friend_peermap,
2922                                                           &finger_identity)));
2923
2924     first_trail_hop->trails_count++;
2925     GNUNET_free (new_entry);
2926     return;
2927   }
2928
2929   GNUNET_assert (NULL !=
2930                 (first_trail_hop =
2931                        GNUNET_CONTAINER_multipeermap_get (friend_peermap,
2932                                                           &finger_trail[0])));
2933   new_entry->trails_count = 1;
2934   first_trail_hop->trails_count++;
2935
2936   /* Copy the finger trail into trail. */
2937   trail = GNUNET_new (struct Trail);
2938   while (i < finger_trail_length)
2939   {
2940     struct Trail_Element *element = GNUNET_new (struct Trail_Element);
2941
2942     element->next = NULL;
2943     element->prev = NULL;
2944     element->peer = finger_trail[i];
2945     GNUNET_CONTAINER_DLL_insert_tail (trail->trail_head,
2946                                       trail->trail_tail,
2947                                       element);
2948     i++;
2949   }
2950
2951   /* Add trail to trail list. */
2952   new_entry->trail_list[0].trail_head = trail->trail_head;
2953   new_entry->trail_list[0].trail_tail = trail->trail_tail;
2954   new_entry->trail_list[0].trail_length = finger_trail_length;
2955   new_entry->trail_list[0].trail_id = trail_id;
2956   new_entry->trail_list[0].is_present = GNUNET_YES;
2957   finger_table[finger_table_index] = *new_entry;
2958   GNUNET_free (new_entry);
2959   return;
2960 }
2961
2962
2963 /**
2964  * Scan the trail to check if there is any other friend in the trail other than
2965  * first hop. If yes then shortcut the trail, send trail compression message to
2966  * peers which are no longer part of trail and send back the updated trail
2967  * and trail_length to calling function.
2968  * @param finger_identity Finger whose trail we will scan.
2969  * @param finger_trail [in, out] Trail to reach from source to finger,
2970  * @param finger_trail_length  Total number of peers in original finger_trail.
2971  * @param finger_trail_id Unique identifier of the finger trail.
2972  * @return updated trail length in case we shortcut the trail, else original
2973  *         trail length.
2974  */
2975 static struct GNUNET_PeerIdentity *
2976 scan_and_compress_trail (struct GNUNET_PeerIdentity finger_identity,
2977                          const struct GNUNET_PeerIdentity *trail,
2978                          unsigned int trail_length,
2979                          struct GNUNET_HashCode trail_id,
2980                          int *new_trail_length)
2981 {
2982   struct FriendInfo *target_friend;
2983   struct GNUNET_PeerIdentity *new_trail;
2984   unsigned int i;
2985
2986   /* I am my own finger. */
2987   if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &finger_identity))
2988   {
2989     *new_trail_length = 0;
2990     return NULL;
2991   }
2992
2993   if (0 == trail_length)
2994   {
2995     *new_trail_length = 0;
2996     return NULL;
2997   }
2998
2999   /* If finger identity is a friend. */
3000   if (NULL != GNUNET_CONTAINER_multipeermap_get (friend_peermap, &finger_identity))
3001   {
3002     *new_trail_length = 0;
3003
3004     /* If there is trail to reach this finger/friend */
3005     if (trail_length > 0)
3006     {
3007       /* Finger is your first friend. */
3008       GDS_ROUTING_update_trail_next_hop (trail_id, finger_identity);
3009       GNUNET_assert (NULL !=
3010                     (target_friend =
3011                      GNUNET_CONTAINER_multipeermap_get (friend_peermap,
3012                                                         &trail[0])));
3013
3014
3015       GDS_NEIGHBOURS_send_trail_compression (my_identity,
3016                                              trail_id, finger_identity,
3017                                              target_friend);
3018     }
3019     return NULL;
3020   }
3021
3022   /*  For other cases, when its neither a friend nor my own identity.*/
3023   for (i = trail_length - 1; i > 0; i--)
3024   {
3025     /* If the element at this index in trail is a friend. */
3026     if (NULL != GNUNET_CONTAINER_multipeermap_get (friend_peermap, &trail[i]))
3027     {
3028       struct FriendInfo *target_friend;
3029       int j = 0;
3030
3031       GNUNET_assert (NULL !=
3032                     (target_friend =
3033                      GNUNET_CONTAINER_multipeermap_get (friend_peermap,
3034                                                         &trail[0])));
3035       GDS_ROUTING_update_trail_next_hop (trail_id, trail[i]);
3036       GDS_NEIGHBOURS_send_trail_compression (my_identity,
3037                                              trail_id, trail[i],
3038                                              target_friend);
3039
3040
3041       /* Copy the trail from index i to index (trail_length -1) into a new trail
3042        *  and update new trail length */
3043       new_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * (trail_length - i));
3044       while (i < trail_length)
3045       {
3046         memcpy (&new_trail[j], &trail[i], sizeof(struct GNUNET_PeerIdentity));
3047         j++;
3048         i++;
3049       }
3050       *new_trail_length = j+1;
3051       return new_trail;
3052     }
3053   }
3054
3055   /* If we did not compress the trail, return the original trail back.*/
3056   *new_trail_length = trail_length;
3057   new_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * trail_length);  
3058   memcpy (new_trail, trail, trail_length * sizeof (struct GNUNET_PeerIdentity));
3059   return new_trail;
3060 }
3061
3062
3063 /**
3064  * Periodic task to verify current successor. There can be multiple trails to reach
3065  * to successor, choose the shortest one and send verify successor message
3066  * across that trail.
3067  * @param cls closure for this task
3068  * @param tc the context under which the task is running
3069  */
3070 static void
3071 send_verify_successor_message (void *cls,
3072                                 const struct GNUNET_SCHEDULER_TaskContext *tc)
3073 {
3074   struct FriendInfo *target_friend;
3075   struct GNUNET_HashCode trail_id;
3076   int i;
3077   struct GNUNET_TIME_Relative next_send_time;
3078   struct Trail *trail;
3079   struct Trail_Element *element;
3080   unsigned int trail_length;
3081   unsigned int j = 0;
3082   struct FingerInfo *successor;
3083
3084   /* Schedule another send_find_finger_trail_message task. */
3085   next_send_time.rel_value_us =
3086       DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us +
3087       GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
3088                                 DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us);
3089   send_verify_successor_task =
3090       GNUNET_SCHEDULER_add_delayed (next_send_time, &send_verify_successor_message,
3091                                     NULL);
3092
3093   successor = &finger_table[0];
3094   for (i = 0; i < successor->trails_count; i++)
3095   {
3096     trail = &successor->trail_list[i];
3097     if(GNUNET_YES == trail->is_present)
3098       break;
3099   }
3100   
3101   if (i == successor->trails_count)
3102     return;
3103   
3104   GNUNET_assert(0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity,
3105                                                       &successor->finger_identity));
3106
3107   /* Trail stored at this index. */
3108   GNUNET_assert (GNUNET_YES == trail->is_present);
3109   
3110   /* Code for testing ONLY: Store the successor for path tracking */
3111   if (track_topology &&  (NULL != GDS_stats))
3112   {
3113     char *my_id_str;
3114     char *succ_id_str;
3115     char *key;
3116     
3117     my_id_str = GNUNET_strdup (GNUNET_i2s (&my_identity));
3118     succ_id_str = GNUNET_strdup (GNUNET_i2s
3119                                  (&successor->finger_identity));
3120     GNUNET_asprintf (&key, "XDHT:%s:%s", my_id_str, succ_id_str);
3121     GNUNET_free (my_id_str);
3122     GNUNET_free (succ_id_str);
3123     GNUNET_STATISTICS_update (GDS_stats, key, 1, 0);
3124     GNUNET_free (key);
3125   }
3126   
3127   trail_id = trail->trail_id;
3128   trail_length = trail->trail_length;
3129   
3130   if (trail_length > 0)
3131   {
3132      /* Copy the trail into peer list. */
3133     struct GNUNET_PeerIdentity peer_list[trail_length];
3134
3135     element = trail->trail_head;
3136     while (j < trail_length)
3137     {
3138       peer_list[j] = element->peer;
3139       element = element->next;
3140       j++;
3141     }
3142
3143     GNUNET_assert (NULL != (target_friend =
3144                             GNUNET_CONTAINER_multipeermap_get (friend_peermap,
3145                                                                &peer_list[0])));
3146     GDS_NEIGHBOURS_send_verify_successor_message (my_identity,
3147                                                   successor->finger_identity,
3148                                                   trail_id, peer_list, trail_length,
3149                                                   target_friend);
3150     return;
3151   }
3152   else
3153   {
3154     GNUNET_assert (NULL != (target_friend =
3155                             GNUNET_CONTAINER_multipeermap_get (friend_peermap,
3156                                                                &successor->finger_identity)));
3157     GDS_NEIGHBOURS_send_verify_successor_message (my_identity,
3158                                                   successor->finger_identity,
3159                                                   trail_id, NULL, 0,
3160                                                   target_friend);
3161     return;
3162   }
3163 }
3164
3165
3166 /**
3167  * Update the current search finger index.
3168  *
3169  * FIXME document parameters!
3170  */
3171 static void
3172 update_current_search_finger_index (struct GNUNET_PeerIdentity finger_identity,
3173                                     unsigned int finger_table_index)
3174 {
3175   struct FingerInfo *successor;
3176
3177   /* FIXME correct this: only move current index periodically */
3178   if (finger_table_index != current_search_finger_index)
3179     return;
3180
3181   successor = &finger_table[0];
3182   GNUNET_assert (GNUNET_YES == successor->is_present);
3183
3184   /* We were looking for immediate successor.  */
3185   if (0 == current_search_finger_index)
3186   {
3187     /* Start looking for immediate predecessor. */
3188     current_search_finger_index = PREDECESSOR_FINGER_ID;
3189
3190     if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &finger_identity))
3191     {
3192       if (GNUNET_SCHEDULER_NO_TASK == send_verify_successor_task)
3193         send_verify_successor_task = GNUNET_SCHEDULER_add_now (&send_verify_successor_message, NULL);
3194     }
3195
3196     return;
3197   }
3198
3199   current_search_finger_index = current_search_finger_index - 1;
3200   return;
3201 }
3202
3203
3204 /**
3205  * Get the least significant bit set in val.
3206  *
3207  * @param val Value
3208  * @return Position of first bit set, 65 in case of error.
3209  */
3210 static unsigned int
3211 find_set_bit (uint64_t val)
3212 {
3213   uint64_t i;
3214   unsigned int pos;
3215
3216   i = 1;
3217   pos = 0;
3218
3219   while (!(i & val))
3220   {
3221     i = i << 1;
3222     pos++;
3223     if (pos > 63)
3224     {
3225       GNUNET_break (0);
3226       return 65;
3227     }
3228   }
3229
3230   if (val/i != 1)
3231     return 65; /* Some other bit was set to 1 as well. */
3232
3233   return pos;
3234 }
3235
3236
3237 /**
3238  * Calculate finger_table_index from initial 64 bit finger identity value that
3239  * we send in trail setup message.
3240  * @param ultimate_destination_finger_value Value that we calculated from our
3241  *                                          identity and finger_table_index.
3242  * @param is_predecessor Is the entry for predecessor or not?
3243  * @return finger_table_index Value between 0 <= finger_table_index <= 64
3244  *         finger_table_index > PREDECESSOR_FINGER_ID, if error occurs.
3245  */
3246 static unsigned int
3247 get_finger_table_index (uint64_t ultimate_destination_finger_value,
3248                         unsigned int is_predecessor)
3249 {
3250   uint64_t my_id64;
3251   uint64_t diff;
3252   unsigned int finger_table_index;
3253
3254   memcpy (&my_id64, &my_identity, sizeof (uint64_t));
3255   my_id64 = GNUNET_ntohll (my_id64);
3256
3257   /* Is this a predecessor finger? */
3258   if (1 == is_predecessor)
3259   {
3260     diff =  my_id64 - ultimate_destination_finger_value;
3261     if (1 == diff)
3262       finger_table_index = PREDECESSOR_FINGER_ID;
3263     else
3264       finger_table_index = PREDECESSOR_FINGER_ID + 1; //error value
3265
3266   }
3267   else
3268   {
3269     diff = ultimate_destination_finger_value - my_id64;
3270     finger_table_index = find_set_bit (diff);
3271   }
3272   return finger_table_index;
3273 }
3274
3275
3276 /**
3277  * Remove finger and its associated data structures from finger table.
3278  * @param finger Finger to be removed.
3279  */
3280 static void
3281 remove_existing_finger (struct FingerInfo *existing_finger,
3282                         unsigned int finger_table_index)
3283 {
3284   struct FingerInfo *finger;
3285
3286   finger = &finger_table[finger_table_index];
3287   GNUNET_assert (GNUNET_YES == finger->is_present);
3288
3289   /* If I am my own finger, then we have no trails. */
3290   if (0 == GNUNET_CRYPTO_cmp_peer_identity (&finger->finger_identity,
3291                                             &my_identity))
3292   {
3293     finger->is_present = GNUNET_NO;
3294     memset ((void *)&finger_table[finger_table_index], 0,
3295             sizeof (finger_table[finger_table_index]));
3296     return;
3297   }
3298
3299   /* For all other fingers, send trail teardown across all the trails to reach
3300    finger, and free the finger. */
3301   send_all_finger_trails_teardown (finger);
3302   free_finger (finger, finger_table_index);
3303   return;
3304 }
3305
3306
3307 /**
3308  * Check if there is already an entry in finger_table at finger_table_index.
3309  * We get the finger_table_index from 64bit finger value we got from the network.
3310  * -- If yes, then select the closest finger.
3311  *   -- If new and existing finger are same, then check if you can store more
3312  *      trails.
3313  *      -- If yes then add trail, else keep the best trails to reach to the
3314  *         finger.
3315  *   -- If the new finger is closest, remove the existing entry, send trail
3316  *      teardown message across all the trails to reach the existing entry.
3317  *      Add the new finger.
3318  *  -- If new and existing finger are different, and existing finger is closest
3319  *     then do nothing.
3320  * -- Update current_search_finger_index.
3321  * @param finger_identity Peer Identity of new finger
3322  * @param finger_trail Trail to reach the new finger
3323  * @param finger_trail_length Total number of peers in @a new_finger_trail.
3324  * @param is_predecessor Is this entry for predecessor in finger_table?
3325  * @param finger_value 64 bit value of finger identity that we got from network.
3326  * @param finger_trail_id Unique identifier of @finger_trail.
3327  */
3328 static void
3329 finger_table_add (struct GNUNET_PeerIdentity finger_identity,
3330                   const struct GNUNET_PeerIdentity *finger_trail,
3331                   unsigned int finger_trail_length,
3332                   unsigned int is_predecessor,
3333                   uint64_t finger_value,
3334                   struct GNUNET_HashCode finger_trail_id)
3335 {
3336   struct FingerInfo *existing_finger;
3337   const struct GNUNET_PeerIdentity *closest_peer;
3338   struct FingerInfo *successor;
3339   int updated_finger_trail_length;
3340   unsigned int finger_table_index;
3341
3342   /* Get the finger_table_index corresponding to finger_value we got from network.*/
3343   finger_table_index = get_finger_table_index (finger_value, is_predecessor);
3344
3345   /* Invalid finger_table_index. */
3346   if ((finger_table_index > PREDECESSOR_FINGER_ID))
3347   {
3348     GNUNET_break_op (0);
3349     return;
3350   }
3351
3352   /* New entry same as successor. */
3353   if ((0 != finger_table_index) &&
3354       (PREDECESSOR_FINGER_ID != finger_table_index))
3355   {
3356     successor = &finger_table[0];
3357     if (GNUNET_NO == successor->is_present)
3358     {
3359       GNUNET_break_op (0);
3360       return;
3361     }
3362     if (0 == GNUNET_CRYPTO_cmp_peer_identity (&finger_identity,
3363                                               &successor->finger_identity))
3364     {
3365       current_search_finger_index = 0;
3366       /* We slow down the find_finger_trail_task as we have completed the circle. */
3367       next_send_time = GNUNET_TIME_STD_BACKOFF(next_send_time);
3368      
3369       return;
3370     }
3371     
3372     struct FingerInfo prev_finger;
3373     prev_finger = finger_table[finger_table_index - 1];
3374     if (0 == GNUNET_CRYPTO_cmp_peer_identity (&finger_identity,
3375                                               &prev_finger.finger_identity))
3376     {
3377        current_search_finger_index--;
3378        return;
3379     }
3380   }
3381
3382   existing_finger = &finger_table[finger_table_index];
3383
3384   /* No entry present in finger_table for given finger map index. */
3385   if (GNUNET_NO == existing_finger->is_present)
3386   {
3387     struct GNUNET_PeerIdentity *updated_trail;
3388
3389     /* Shorten the trail if possible. */
3390     updated_finger_trail_length = finger_trail_length;
3391     updated_trail = scan_and_compress_trail (finger_identity, finger_trail,
3392                                              finger_trail_length,
3393                                              finger_trail_id,
3394                                              &updated_finger_trail_length);
3395
3396     add_new_finger (finger_identity, updated_trail,
3397                     updated_finger_trail_length,
3398                     finger_trail_id, finger_table_index);
3399     GNUNET_free_non_null(updated_trail);
3400     update_current_search_finger_index (finger_identity,
3401                                         finger_table_index);
3402     return;
3403   }
3404
3405
3406   /* If existing entry and finger identity are not same. */
3407   if (0 != GNUNET_CRYPTO_cmp_peer_identity (&(existing_finger->finger_identity),
3408                                             &finger_identity))
3409   {
3410     closest_peer = select_closest_peer (&existing_finger->finger_identity,
3411                                         &finger_identity,
3412                                         finger_value,
3413                                         is_predecessor);
3414
3415     /* If the new finger is the closest peer. */
3416     if (0 == GNUNET_CRYPTO_cmp_peer_identity (&finger_identity, closest_peer))
3417     {
3418       struct GNUNET_PeerIdentity *updated_trail;
3419       /* Shorten the trail if possible. */
3420       updated_finger_trail_length = finger_trail_length;
3421       updated_trail =
3422         scan_and_compress_trail (finger_identity, finger_trail,
3423                                  finger_trail_length, finger_trail_id,
3424                                  &updated_finger_trail_length);
3425       remove_existing_finger (existing_finger, finger_table_index);
3426       add_new_finger (finger_identity, updated_trail, updated_finger_trail_length,
3427                       finger_trail_id, finger_table_index);
3428       GNUNET_free_non_null((struct GNUNET_PeerIdentity *)updated_trail);
3429     }
3430     else
3431     {
3432       /* Existing finger is the closest one. We need to send trail teardown
3433          across the trail setup in routing table of all the peers. */
3434       if (0 != GNUNET_CRYPTO_cmp_peer_identity (&finger_identity, &my_identity))
3435       {
3436         if (finger_trail_length > 0)
3437           GDS_NEIGHBOURS_send_trail_teardown (finger_trail_id,
3438                                               GDS_ROUTING_SRC_TO_DEST,
3439                                               finger_trail[0]);
3440         else
3441           GDS_NEIGHBOURS_send_trail_teardown (finger_trail_id,
3442                                               GDS_ROUTING_SRC_TO_DEST,
3443                                               finger_identity);
3444       }
3445     }
3446   }
3447   else
3448   {
3449     /* If both new and existing entry are same as my_identity, then do nothing. */
3450     if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(existing_finger->finger_identity),
3451                                               &my_identity))
3452     {
3453       return;
3454     }
3455     /* If the existing finger is not a friend. */
3456     if (NULL ==
3457         GNUNET_CONTAINER_multipeermap_get (friend_peermap,
3458                                            &existing_finger->finger_identity))
3459     {
3460       struct GNUNET_PeerIdentity *updated_trail;
3461
3462       /* Shorten the trail if possible. */
3463       updated_finger_trail_length = finger_trail_length;
3464       updated_trail =
3465          scan_and_compress_trail (finger_identity, finger_trail,
3466                                   finger_trail_length, finger_trail_id,
3467                                   &updated_finger_trail_length);
3468       /* If there is space to store more trails. */
3469       if (existing_finger->trails_count < MAXIMUM_TRAILS_PER_FINGER)
3470         add_new_trail (existing_finger, updated_trail,
3471                        updated_finger_trail_length, finger_trail_id);
3472       else
3473         select_and_replace_trail (existing_finger, updated_trail,
3474                                   updated_finger_trail_length, finger_trail_id);
3475
3476     }
3477   }
3478   update_current_search_finger_index (finger_identity, finger_table_index);
3479   return;
3480 }
3481
3482 /**
3483  * Core handler for P2P put messages.
3484  * @param cls closure
3485  * @param peer sender of the request
3486  * @param message message
3487  * @return #GNUNET_OK to keep the connection open,
3488  *         #GNUNET_SYSERR to close it (signal serious error)
3489  */
3490 static int
3491 handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer,
3492                     const struct GNUNET_MessageHeader *message)
3493 {
3494   struct PeerPutMessage *put;
3495   struct GNUNET_PeerIdentity *put_path;
3496   struct GNUNET_PeerIdentity best_known_dest;
3497   struct GNUNET_HashCode intermediate_trail_id;
3498   struct GNUNET_PeerIdentity *next_hop;
3499   enum GNUNET_DHT_RouteOption options;
3500   struct GNUNET_HashCode test_key;
3501   void *payload;
3502   size_t msize;
3503   uint32_t putlen;
3504   size_t payload_size;
3505   uint64_t key_value;
3506
3507   msize = ntohs (message->size);
3508   if (msize < sizeof (struct PeerPutMessage))
3509   {
3510     GNUNET_break_op (0);
3511     return GNUNET_OK;
3512   }
3513
3514   put = (struct PeerPutMessage *) message;
3515   putlen = ntohl (put->put_path_length);
3516
3517
3518   if ((msize <
3519        sizeof (struct PeerPutMessage) +
3520        putlen * sizeof (struct GNUNET_PeerIdentity)) ||
3521       (putlen >
3522        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
3523   {
3524     GNUNET_break_op (0);
3525     return GNUNET_OK;
3526   }
3527
3528   GNUNET_STATISTICS_update (GDS_stats,
3529                             gettext_noop
3530                             ("# Bytes received from other peers"), (int64_t) msize,
3531                             GNUNET_NO);
3532   
3533   best_known_dest = put->best_known_destination;
3534   put_path = (struct GNUNET_PeerIdentity *) &put[1];
3535   payload = &put_path[putlen];
3536   options = ntohl (put->options);
3537   intermediate_trail_id = put->intermediate_trail_id;
3538
3539   payload_size = msize - (sizeof (struct PeerPutMessage) +
3540                           putlen * sizeof (struct GNUNET_PeerIdentity));
3541
3542   switch (GNUNET_BLOCK_get_key (GDS_block_context, ntohl (put->block_type),
3543                                 payload, payload_size, &test_key))
3544   {
3545     case GNUNET_YES:
3546       if (0 != memcmp (&test_key, &put->key, sizeof (struct GNUNET_HashCode)))
3547       {
3548         char *put_s = GNUNET_strdup (GNUNET_h2s_full (&put->key));
3549         GNUNET_break_op (0);
3550         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3551                     "PUT with key `%s' for block with key %s\n",
3552                      put_s, GNUNET_h2s_full (&test_key));
3553         GNUNET_free (put_s);
3554         return GNUNET_OK;
3555       }
3556     break;
3557     case GNUNET_NO:
3558       GNUNET_break_op (0);
3559       return GNUNET_OK;
3560     case GNUNET_SYSERR:
3561       /* cannot verify, good luck */
3562       break;
3563   }
3564
3565    if (ntohl (put->block_type) == GNUNET_BLOCK_TYPE_REGEX) /* FIXME: do for all tpyes */
3566   {
3567     switch (GNUNET_BLOCK_evaluate (GDS_block_context,
3568                                    ntohl (put->block_type),
3569                                    NULL,    /* query */
3570                                    NULL, 0, /* bloom filer */
3571                                    NULL, 0, /* xquery */
3572                                    payload, payload_size))
3573     {
3574     case GNUNET_BLOCK_EVALUATION_OK_MORE:
3575     case GNUNET_BLOCK_EVALUATION_OK_LAST:
3576       break;
3577
3578     case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE:
3579     case GNUNET_BLOCK_EVALUATION_RESULT_INVALID:
3580     case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT:
3581     case GNUNET_BLOCK_EVALUATION_REQUEST_VALID:
3582     case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID:
3583     case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED:
3584     default:
3585       GNUNET_break_op (0);
3586       return GNUNET_OK;
3587     }
3588   }
3589
3590   /* extend 'put path' by sender */
3591   struct GNUNET_PeerIdentity pp[putlen + 1];
3592   if (0 != (options & GNUNET_DHT_RO_RECORD_ROUTE))
3593   {
3594     memcpy (pp, put_path, putlen * sizeof (struct GNUNET_PeerIdentity));
3595     pp[putlen] = *peer;
3596     putlen++;
3597   }
3598   else
3599     putlen = 0;
3600
3601   memcpy (&key_value, &(put->key), sizeof (uint64_t));
3602   if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&best_known_dest, &my_identity)))
3603   {
3604     next_hop = GDS_ROUTING_get_next_hop (intermediate_trail_id,
3605                                          GDS_ROUTING_SRC_TO_DEST);
3606     if (NULL == next_hop)
3607     {
3608       GNUNET_STATISTICS_update (GDS_stats,
3609                                 gettext_noop ("# Next hop to forward the packet not found "
3610                                 "trail setup request, packet dropped."),
3611                                 1, GNUNET_NO);
3612       return GNUNET_SYSERR;
3613     }
3614   }
3615   else
3616   {
3617     struct Closest_Peer successor;
3618     key_value = GNUNET_ntohll (key_value);
3619     successor = find_successor (key_value, GDS_FINGER_TYPE_NON_PREDECESSOR);
3620     next_hop = GNUNET_new (struct GNUNET_PeerIdentity);
3621     *next_hop = successor.next_hop;
3622     intermediate_trail_id = successor.trail_id;
3623     best_known_dest = successor.best_known_destination;
3624   }
3625
3626   GDS_CLIENTS_process_put (options,
3627                            ntohl (put->block_type),
3628                            ntohl (put->hop_count),
3629                            ntohl (put->desired_replication_level),
3630                            putlen, pp,
3631                            GNUNET_TIME_absolute_ntoh (put->expiration_time),
3632                            &put->key,
3633                            payload,
3634                            payload_size);
3635
3636   /* I am the final destination */
3637   if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &best_known_dest))
3638   {
3639     GDS_DATACACHE_handle_put (GNUNET_TIME_absolute_ntoh (put->expiration_time),
3640                               &(put->key),putlen, pp, ntohl (put->block_type),
3641                               payload_size, payload);
3642   }
3643   else
3644   {
3645     GDS_NEIGHBOURS_send_put (&put->key,
3646                              ntohl (put->block_type),ntohl (put->options),
3647                              ntohl (put->desired_replication_level),
3648                              best_known_dest, intermediate_trail_id, next_hop,
3649                              ntohl (put->hop_count), putlen, pp,
3650                              GNUNET_TIME_absolute_ntoh (put->expiration_time),
3651                              payload, payload_size);
3652   }
3653   return GNUNET_OK;
3654 }
3655
3656
3657 /**
3658  * Core handler for p2p get requests.
3659  *
3660  * @param cls closure
3661  * @param peer sender of the request
3662  * @param message message
3663  * @return #GNUNET_OK to keep the connection open,
3664  *         #GNUNET_SYSERR to close it (signal serious error)
3665  */
3666 static int
3667 handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer,
3668                     const struct GNUNET_MessageHeader *message)
3669 {
3670   const struct PeerGetMessage *get;
3671   const struct GNUNET_PeerIdentity *get_path;
3672   struct GNUNET_PeerIdentity best_known_dest;
3673   struct GNUNET_HashCode intermediate_trail_id;
3674   struct GNUNET_PeerIdentity *next_hop;
3675   uint32_t get_length;
3676   uint64_t key_value;
3677   size_t msize;
3678
3679   msize = ntohs (message->size);
3680   if (msize < sizeof (struct PeerGetMessage))
3681   {
3682     GNUNET_break_op (0);
3683     return GNUNET_YES;
3684   }
3685
3686   get = (const struct PeerGetMessage *)message;
3687   get_length = ntohl (get->get_path_length);
3688   best_known_dest = get->best_known_destination;
3689   intermediate_trail_id = get->intermediate_trail_id;
3690   get_path = (const struct GNUNET_PeerIdentity *)&get[1];
3691
3692   if ((msize <
3693        sizeof (struct PeerGetMessage) +
3694        get_length * sizeof (struct GNUNET_PeerIdentity)) ||
3695        (get_length >
3696         GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
3697   {
3698     GNUNET_break_op (0);
3699     return GNUNET_YES;
3700   }
3701
3702   GNUNET_STATISTICS_update (GDS_stats,
3703                             gettext_noop
3704                             ("# Bytes received from other peers"), msize,
3705                             GNUNET_NO);
3706   
3707   /* Add sender to get path */
3708   struct GNUNET_PeerIdentity gp[get_length + 1];
3709   if (get_length > 0)
3710     memcpy (gp, get_path, get_length * sizeof (struct GNUNET_PeerIdentity));
3711   gp[get_length] = *peer;
3712   get_length = get_length + 1;
3713
3714   memcpy (&key_value, &(get->key), sizeof (uint64_t));
3715   key_value = GNUNET_ntohll (key_value);
3716
3717   /* I am not the final destination. I am part of trail to reach final dest. */
3718   if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&best_known_dest, &my_identity)))
3719   {
3720     next_hop = GDS_ROUTING_get_next_hop (intermediate_trail_id,
3721                                          GDS_ROUTING_SRC_TO_DEST);
3722     if (NULL == next_hop)
3723     {
3724       GNUNET_STATISTICS_update (GDS_stats,
3725                                 gettext_noop ("# Next hop to forward the packet not found "
3726                                 "GET request, packet dropped."),
3727                                 1, GNUNET_NO);
3728       return GNUNET_SYSERR;
3729     }
3730   }
3731   else
3732   {
3733     struct Closest_Peer successor;
3734
3735     successor = find_successor (key_value, GDS_FINGER_TYPE_NON_PREDECESSOR);
3736     next_hop = GNUNET_new (struct GNUNET_PeerIdentity);
3737     *next_hop = successor.next_hop;
3738     best_known_dest = successor.best_known_destination;
3739     intermediate_trail_id = successor.trail_id;
3740   }
3741
3742   GDS_CLIENTS_process_get (get->options, get->block_type,get->hop_count,
3743                            get->desired_replication_level, get->get_path_length,
3744                            gp, &get->key);
3745   /* I am the final destination. */
3746   if (0 == GNUNET_CRYPTO_cmp_peer_identity(&my_identity, &best_known_dest))
3747   {
3748     struct GNUNET_PeerIdentity final_get_path[get_length+1];
3749
3750     memcpy (final_get_path, gp, get_length * sizeof (struct GNUNET_PeerIdentity));
3751     memcpy (&final_get_path[get_length], &my_identity, sizeof (struct GNUNET_PeerIdentity));
3752     get_length = get_length + 1;
3753
3754     GDS_DATACACHE_handle_get (&(get->key),(get->block_type), NULL, 0, NULL, 0,
3755                               get_length, final_get_path,
3756                               &final_get_path[get_length-2], &my_identity);
3757   }
3758   else
3759   {
3760     GDS_NEIGHBOURS_send_get (&(get->key), get->block_type, get->options,
3761                              get->desired_replication_level, best_known_dest,
3762                              intermediate_trail_id, next_hop, 0,
3763                              get_length, gp);
3764   }
3765   return GNUNET_YES;
3766 }
3767
3768
3769 /**
3770  * Core handler for get result
3771  * @param cls closure
3772  * @param peer sender of the request
3773  * @param message message
3774  * @return #GNUNET_OK to keep the connection open,
3775  *         #GNUNET_SYSERR to close it (signal serious error)
3776  */
3777 static int
3778 handle_dht_p2p_get_result (void *cls, const struct GNUNET_PeerIdentity *peer,
3779                            const struct GNUNET_MessageHeader *message)
3780 {
3781   const struct PeerGetResultMessage *get_result;
3782   const struct GNUNET_PeerIdentity *get_path;
3783   const struct GNUNET_PeerIdentity *put_path;
3784   const void *payload;
3785   size_t payload_size;
3786   size_t msize;
3787   unsigned int getlen;
3788   unsigned int putlen;
3789   int current_path_index;
3790
3791   msize = ntohs (message->size);
3792   if (msize < sizeof (struct PeerGetResultMessage))
3793   {
3794     GNUNET_break_op (0);
3795     return GNUNET_YES;
3796   }
3797
3798   get_result = (const struct PeerGetResultMessage *)message;
3799   getlen = ntohl (get_result->get_path_length);
3800   putlen = ntohl (get_result->put_path_length);
3801
3802   if ((msize <
3803        sizeof (struct PeerGetResultMessage) +
3804        getlen * sizeof (struct GNUNET_PeerIdentity) +
3805        putlen * sizeof (struct GNUNET_PeerIdentity)) ||
3806       (getlen >
3807        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity) ||
3808       (putlen >
3809          GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity))))
3810   {
3811     GNUNET_break_op (0);
3812     return GNUNET_YES;
3813   }
3814
3815   GNUNET_STATISTICS_update (GDS_stats,
3816                             gettext_noop
3817                             ("# Bytes received from other peers"), msize,
3818                             GNUNET_NO);
3819   
3820   put_path = (const struct GNUNET_PeerIdentity *) &get_result[1];
3821   get_path = &put_path[putlen];
3822   payload = (const void *) &get_path[getlen];
3823   payload_size = msize - (sizeof (struct PeerGetResultMessage) +
3824                          (getlen + putlen) * sizeof (struct GNUNET_PeerIdentity));
3825
3826   if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &(get_path[0]))))
3827   {
3828     GDS_CLIENTS_handle_reply (get_result->expiration_time, &(get_result->key),
3829                               getlen, get_path, putlen,
3830                               put_path, get_result->type, payload_size, payload);
3831     return GNUNET_YES;
3832   }
3833   else
3834   {
3835     current_path_index = search_my_index (get_path, getlen);
3836     if (-1 == current_path_index )
3837     {
3838       GNUNET_break (0);
3839       return GNUNET_SYSERR;
3840     }
3841     GDS_NEIGHBOURS_send_get_result (&(get_result->key), get_result->type,
3842                                     &get_path[current_path_index - 1],
3843                                     &(get_result->querying_peer), putlen, put_path,
3844                                     getlen, get_path, get_result->expiration_time,
3845                                     payload, payload_size);
3846     return GNUNET_YES;
3847   }
3848   return GNUNET_SYSERR;
3849 }
3850
3851
3852 /**
3853  * Find the next hop to pass trail setup message. First find the local best known
3854  * hop from your own identity, friends and finger. If you were part of trail,
3855  * then get the next hop from routing table. Compare next_hop from routing table
3856  * and local best known hop, and return the closest one to final_dest_finger_val
3857  * @param final_dest_finger_val 64 bit value of finger identity
3858  * @param intermediate_trail_id If you are part of trail to reach to some other
3859  *                              finger, then it is the trail id to reach to
3860  *                              that finger, else set to 0.
3861  * @param is_predecessor Are we looking for closest successor or predecessor.
3862  * @param current_dest In case you are part of trail, then finger to which
3863  *                     we should forward the message. Else my own identity
3864  * @return Closest Peer for @a final_dest_finger_val
3865  */
3866 static struct Closest_Peer
3867 get_local_best_known_next_hop (uint64_t final_dest_finger_val,
3868                                struct GNUNET_HashCode intermediate_trail_id,
3869                                unsigned int is_predecessor,
3870                                 struct GNUNET_PeerIdentity prev_hop,
3871                                struct GNUNET_PeerIdentity source,
3872                                struct GNUNET_PeerIdentity *current_dest)
3873 {
3874   struct Closest_Peer peer;
3875
3876   /* Find a local best known peer. */
3877   peer = find_successor (final_dest_finger_val, is_predecessor);//FIXME: chnage to better name
3878
3879   /* Am I just a part of a trail towards a finger (current_destination)? */
3880   /* Select best successor among one found locally and current_destination
3881    * that we got from network.*/
3882   if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity, current_dest) &&
3883       0 != GNUNET_CRYPTO_cmp_peer_identity (&peer.best_known_destination,
3884                                             current_dest))
3885   {
3886     const struct GNUNET_PeerIdentity *closest_peer;
3887
3888     closest_peer = select_closest_peer (&peer.best_known_destination,
3889                                         current_dest,
3890                                         final_dest_finger_val,
3891                                         is_predecessor);
3892
3893     /* Is current dest (end point of the trail of which I am a part) closest_peer? */
3894     if (0 == GNUNET_CRYPTO_cmp_peer_identity (current_dest, closest_peer))
3895     {
3896       struct GNUNET_PeerIdentity *next_hop;
3897       
3898       next_hop = GDS_ROUTING_get_next_hop (intermediate_trail_id,
3899                                            GDS_ROUTING_SRC_TO_DEST);
3900       /* It may happen that trail teardown message got delayed and hence,
3901          the previous hop sent the message over intermediate trail id.In that
3902          case next_hop could be NULL. */
3903       if(NULL != next_hop)
3904       {
3905          peer.next_hop = *next_hop;
3906          peer.best_known_destination =  *current_dest;
3907          peer.trail_id = intermediate_trail_id;
3908       }
3909     }
3910   }
3911   return peer;
3912 }
3913
3914 /*
3915  * Core handle for PeerTrailSetupMessage.
3916  * @param cls closure
3917  * @param message message
3918  * @param peer peer identity this notification is about
3919  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
3920  */
3921 static int
3922 handle_dht_p2p_trail_setup (void *cls, const struct GNUNET_PeerIdentity *peer,
3923                             const struct GNUNET_MessageHeader *message)
3924 {
3925   const struct PeerTrailSetupMessage *trail_setup;
3926   const struct GNUNET_PeerIdentity *trail_peer_list;
3927   struct GNUNET_PeerIdentity current_dest;
3928   struct FriendInfo *target_friend;
3929   struct GNUNET_PeerIdentity source;
3930   uint64_t final_dest_finger_val;
3931   struct GNUNET_HashCode intermediate_trail_id;
3932   struct GNUNET_HashCode trail_id;
3933   unsigned int is_predecessor;
3934   uint32_t trail_length;
3935   unsigned int i;
3936   size_t msize;
3937
3938   msize = ntohs (message->size);
3939   if (msize < sizeof (struct PeerTrailSetupMessage))
3940   {
3941     GNUNET_break_op (0);
3942     return GNUNET_SYSERR;
3943   }
3944
3945   trail_setup = (const struct PeerTrailSetupMessage *) message;
3946   trail_length = (msize - sizeof (struct PeerTrailSetupMessage))/
3947                   sizeof (struct GNUNET_PeerIdentity);
3948   if ((msize - sizeof (struct PeerTrailSetupMessage)) %
3949       sizeof (struct GNUNET_PeerIdentity) != 0)
3950   {
3951     GNUNET_break_op (0);
3952     return GNUNET_OK;
3953   }
3954
3955   GNUNET_STATISTICS_update (GDS_stats,
3956                             gettext_noop
3957                             ("# Bytes received from other peers"), msize,
3958                             GNUNET_NO);
3959   
3960   trail_peer_list = (const struct GNUNET_PeerIdentity *)&trail_setup[1];
3961   current_dest = trail_setup->best_known_destination;
3962   trail_id = trail_setup->trail_id;
3963   final_dest_finger_val =
3964           GNUNET_ntohll (trail_setup->final_destination_finger_value);
3965   source = trail_setup->source_peer;
3966   is_predecessor = ntohl (trail_setup->is_predecessor);
3967   intermediate_trail_id = trail_setup->intermediate_trail_id;
3968
3969   /* Did the friend insert its ID in the trail list? */
3970   if (trail_length > 0 &&
3971       0 != memcmp (&trail_peer_list[trail_length-1], peer, sizeof (*peer)))
3972   {
3973     GNUNET_break_op (0);
3974     return GNUNET_SYSERR;
3975   }
3976   
3977    /* If I was the source and got the message back, then set trail length to 0.*/
3978   if (0 == GNUNET_CRYPTO_cmp_peer_identity(&my_identity, &source))
3979   {
3980     /* IF (!) the peers know the destinations of the trails in their routing
3981      * table, then:
3982      *
3983      * This shoud only happen after 1 hop, since the first message is sent
3984      * to random friend, and we can happen to be on the best trail to the dest.
3985      * If the first friend selects someone else, the request should never come
3986      * back to us.
3987      *
3988      * (TODO)
3989      */
3990     // GNUNET_break_op (1 == trail_length);
3991     trail_length = 0;
3992   }
3993
3994   /* Check if you are present in the trail seen so far? */
3995   if(trail_length > 0)
3996   {
3997     for (i = 0; i < trail_length ; i++)
3998     {
3999       if(0 == GNUNET_CRYPTO_cmp_peer_identity(&trail_peer_list[i],&my_identity))
4000       {
4001         //Here if you already were present in the trail. then you
4002         // shoudl trail length to i + 1
4003         trail_length = i+1;
4004         break;
4005       }
4006     }
4007   }
4008   
4009   /* Is my routing table full?  */
4010   if (GNUNET_YES == GDS_ROUTING_threshold_reached())
4011   {
4012     GNUNET_assert (NULL !=
4013                   (target_friend =
4014                    GNUNET_CONTAINER_multipeermap_get (friend_peermap, peer)));
4015     GDS_NEIGHBOURS_send_trail_rejection (source, final_dest_finger_val,
4016                                          my_identity, is_predecessor,
4017                                          trail_peer_list, trail_length,
4018                                          trail_id, target_friend,
4019                                          CONGESTION_TIMEOUT);
4020     return GNUNET_OK;
4021   }
4022
4023   /* Get the next hop to forward the trail setup request. */
4024   struct Closest_Peer next_peer =
4025           get_local_best_known_next_hop (final_dest_finger_val,
4026                                          intermediate_trail_id,
4027                                          is_predecessor,
4028                                          *peer,
4029                                          source,
4030                                          &current_dest);
4031
4032   /* Am I the final destination? */
4033   if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&next_peer.best_known_destination,
4034                                              &my_identity)))
4035   {
4036     /* If I was not the source of this message for which now I am destination */
4037     if (0 != GNUNET_CRYPTO_cmp_peer_identity (&source, &my_identity))
4038     {
4039       GDS_ROUTING_add (trail_id, *peer, my_identity);
4040     }
4041
4042     if(0 == GNUNET_CRYPTO_cmp_peer_identity (&source, &my_identity))
4043     {
4044       finger_table_add (my_identity, NULL, 0, is_predecessor,
4045                         final_dest_finger_val, trail_id);
4046       return GNUNET_OK;
4047     }
4048
4049     if (trail_length > 0)
4050       target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, peer);
4051     else
4052       target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &source);
4053     if (NULL == target_friend)
4054     {
4055       GNUNET_break_op (0);
4056       return GNUNET_SYSERR;
4057     }
4058
4059     GDS_NEIGHBOURS_send_trail_setup_result (source,
4060                                             my_identity,
4061                                             target_friend, trail_length,
4062                                             trail_peer_list,
4063                                             is_predecessor,
4064                                             final_dest_finger_val,trail_id);
4065   }
4066   else /* I'm not the final destination. */
4067   {
4068     GNUNET_assert (NULL !=
4069                     (target_friend =
4070                       GNUNET_CONTAINER_multipeermap_get (friend_peermap,
4071                                                           &next_peer.next_hop)));
4072
4073     if (0 != GNUNET_CRYPTO_cmp_peer_identity(&my_identity, &source))
4074     {
4075       /* Add yourself to list of peers. */
4076       struct GNUNET_PeerIdentity peer_list[trail_length + 1];
4077
4078       memcpy (peer_list, trail_peer_list,
4079               trail_length * sizeof (struct GNUNET_PeerIdentity));
4080       peer_list[trail_length] = my_identity;
4081
4082       GDS_NEIGHBOURS_send_trail_setup (source,
4083                                        final_dest_finger_val,
4084                                        next_peer.best_known_destination,
4085                                        target_friend, trail_length + 1, peer_list,
4086                                        is_predecessor, trail_id,
4087                                        next_peer.trail_id);
4088     }
4089     else
4090         GDS_NEIGHBOURS_send_trail_setup (source,
4091                                          final_dest_finger_val,
4092                                          next_peer.best_known_destination,
4093                                          target_friend, 0, NULL,
4094                                          is_predecessor, trail_id,
4095                                          next_peer.trail_id);
4096   }
4097   return GNUNET_OK;
4098 }
4099
4100 #if 0
4101 /* FIXME: here we are calculating my_index and comparing also in this function.
4102    And we are doing it again here in this function. Re factor the code. */
4103 /**
4104  * FIXME: Should we call this function everywhere in all the handle functions
4105  * where we have a trail to verify from or a trail id. something like
4106  * if prev hop is not same then drop the message.
4107  * Check if sender_peer and peer from which we should receive the message are
4108  * same or different.
4109  * @param trail_peer_list List of peers in trail
4110  * @param trail_length Total number of peers in @a trail_peer_list
4111  * @param sender_peer Peer from which we got the message.
4112  * @param finger_identity Finger to which trail is setup. It is not part of trail.
4113  * @return #GNUNET_YES if sender_peer and peer from which we should receive the
4114  *                    message are different.
4115  *         #GNUNET_NO if sender_peer and peer from which we should receive the
4116  *                    message are different.
4117  */
4118 static int
4119 is_sender_peer_correct (const struct GNUNET_PeerIdentity *trail_peer_list,
4120                         unsigned int trail_length,
4121                         const struct GNUNET_PeerIdentity *sender_peer,
4122                         struct GNUNET_PeerIdentity finger_identity,
4123                         struct GNUNET_PeerIdentity source_peer)
4124 {
4125   int my_index;
4126
4127   /* I am the source peer. */
4128   if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&source_peer,
4129                                              &my_identity)))
4130   {
4131     /* Is the first element of the trail is sender_peer.*/
4132     if (trail_length > 0)
4133     {
4134       if (0 != GNUNET_CRYPTO_cmp_peer_identity (&trail_peer_list[0],
4135                                                 sender_peer))
4136         return GNUNET_NO;
4137     }
4138     else
4139     {
4140       /* Is finger the sender peer? */
4141       if (0 != GNUNET_CRYPTO_cmp_peer_identity (sender_peer,
4142                                                 &finger_identity))
4143         return GNUNET_NO;
4144     }
4145   }
4146   else
4147   {
4148     /* Get my current location in the trail. */
4149     my_index = search_my_index (trail_peer_list, trail_length);
4150     if (-1 == my_index)
4151       return GNUNET_NO;
4152
4153     /* I am the last element in the trail. */
4154     if ((trail_length - 1) == my_index)
4155     {
4156       /* Is finger the sender_peer? */
4157       if (0 != GNUNET_CRYPTO_cmp_peer_identity (sender_peer,
4158                                                 &finger_identity))
4159         return GNUNET_NO;
4160     }
4161     else
4162     {
4163       /* Is peer after me in trail the sender peer? */
4164       if (0 != GNUNET_CRYPTO_cmp_peer_identity (sender_peer,
4165                                                 &trail_peer_list[my_index + 1]))
4166         return GNUNET_NO;
4167     }
4168   }
4169   return GNUNET_YES;
4170 }
4171 #endif
4172
4173
4174 /**
4175  * FIXME: we should also add a case where we search if we are present in the trail
4176  * twice.
4177  * Core handle for p2p trail setup result messages.
4178  * @param closure
4179  * @param message message
4180  * @param peer sender of this message.
4181  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
4182  */
4183 static int
4184 handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *peer,
4185                                   const struct GNUNET_MessageHeader *message)
4186 {
4187   const struct PeerTrailSetupResultMessage *trail_result;
4188   const struct GNUNET_PeerIdentity *trail_peer_list;
4189   struct GNUNET_PeerIdentity next_hop;
4190   struct FriendInfo *target_friend;
4191   struct GNUNET_PeerIdentity querying_peer;
4192   struct GNUNET_PeerIdentity finger_identity;
4193   uint32_t trail_length;
4194   uint64_t ulitmate_destination_finger_value;
4195   uint32_t is_predecessor;
4196   struct GNUNET_HashCode trail_id;
4197   int my_index;
4198   size_t msize;
4199
4200   msize = ntohs (message->size);
4201   if (msize < sizeof (struct PeerTrailSetupResultMessage))
4202   {
4203     GNUNET_break_op (0);
4204     return GNUNET_YES;
4205   }
4206
4207   trail_result = (const struct PeerTrailSetupResultMessage *) message;
4208   trail_length = (msize - sizeof (struct PeerTrailSetupResultMessage))/
4209                   sizeof (struct GNUNET_PeerIdentity);
4210   if ((msize - sizeof (struct PeerTrailSetupResultMessage)) %
4211       sizeof (struct GNUNET_PeerIdentity) != 0)
4212   {
4213     GNUNET_break_op (0);
4214     return GNUNET_OK;
4215   }
4216
4217   GNUNET_STATISTICS_update (GDS_stats,
4218                             gettext_noop
4219                             ("# Bytes received from other peers"), msize,
4220                             GNUNET_NO);
4221   
4222   is_predecessor = ntohl (trail_result->is_predecessor);
4223   querying_peer = trail_result->querying_peer;
4224   finger_identity = trail_result->finger_identity;
4225   trail_id = trail_result->trail_id;
4226   trail_peer_list = (const struct GNUNET_PeerIdentity *) &trail_result[1];
4227   ulitmate_destination_finger_value =
4228           GNUNET_ntohll (trail_result->ulitmate_destination_finger_value);
4229
4230   /* FIXME: here we are calculating my_index and comparing also in this function.
4231    And we are doing it again here in this function. Re factor the code. */
4232   /* Ensure that sender peer is the peer from which we were expecting the message. */
4233 #if 0
4234   if (GNUNET_NO == is_sender_peer_correct (trail_peer_list,
4235                                            trail_length,
4236                                            peer, finger_identity, querying_peer))
4237   {
4238     GNUNET_break_op (0);
4239     return GNUNET_SYSERR;
4240   }
4241 #endif
4242
4243   /*TODO:URGENT Check if I am already present in the trail. If yes then its an error,
4244    as in trail setup we ensure that it should never happen. */
4245   /* Am I the one who initiated the query? */
4246   if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&querying_peer, &my_identity)))
4247   {
4248     /* If I am my own finger identity, error. */
4249     if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &finger_identity))
4250     {
4251       GNUNET_break_op (0);
4252       return GNUNET_SYSERR;
4253     }
4254     GDS_ROUTING_add (trail_id, my_identity, *peer);
4255     finger_table_add (finger_identity, trail_peer_list, trail_length,
4256                       is_predecessor, ulitmate_destination_finger_value, trail_id);
4257     return GNUNET_YES;
4258   }
4259
4260   /* Get my location in the trail. */
4261   my_index = search_my_index (trail_peer_list, trail_length);
4262   if (-1 == my_index)
4263   {
4264     GNUNET_break_op(0);
4265     return GNUNET_SYSERR;
4266   }
4267
4268   if (my_index == 0)
4269     next_hop = trail_result->querying_peer;
4270   else
4271     next_hop = trail_peer_list[my_index - 1];
4272
4273   target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
4274   if (NULL == target_friend)
4275   {
4276     GNUNET_break_op (0);
4277     return GNUNET_SYSERR;
4278   }
4279
4280   if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_result->querying_peer),
4281                                              &(trail_result->finger_identity))))
4282   {
4283     GNUNET_break_op (0);
4284     return GNUNET_SYSERR;
4285   }
4286
4287   GDS_ROUTING_add (trail_id, next_hop, *peer);
4288
4289   GDS_NEIGHBOURS_send_trail_setup_result (querying_peer, finger_identity,
4290                                           target_friend, trail_length, trail_peer_list,
4291                                           is_predecessor,
4292                                           ulitmate_destination_finger_value,
4293                                           trail_id);
4294   return GNUNET_OK;
4295 }
4296
4297
4298 /**
4299  * Invert the trail.
4300  * @param trail Trail to be inverted
4301  * @param trail_length Total number of peers in the trail.
4302  * @return Updated trail
4303  */
4304 static struct GNUNET_PeerIdentity *
4305 invert_trail (const struct GNUNET_PeerIdentity *trail,
4306               unsigned int trail_length)
4307 {
4308   int i;
4309   int j;
4310   struct GNUNET_PeerIdentity *inverted_trail;
4311
4312   inverted_trail = GNUNET_malloc (sizeof(struct GNUNET_PeerIdentity) *
4313                                   trail_length);
4314   i = 0;
4315   j = trail_length - 1;
4316   while (i < trail_length)
4317   {
4318     inverted_trail[i] = trail[j];
4319     i++;
4320     j--;
4321   }
4322
4323   GNUNET_assert(NULL != GNUNET_CONTAINER_multipeermap_get(friend_peermap,
4324                                                           &inverted_trail[0]));
4325   return inverted_trail;
4326 }
4327
4328
4329 /**
4330  * Return the shortest trail among all the trails to reach to finger from me.
4331  * @param finger Finger
4332  * @param shortest_trail_length[out] Trail length of shortest trail from me
4333  *                                   to @a finger
4334  * @return Shortest trail.
4335  */
4336 static struct GNUNET_PeerIdentity *
4337 get_shortest_trail (struct FingerInfo *finger,
4338                     unsigned int *trail_length)
4339 {
4340   struct Trail *trail;
4341   unsigned int flag = 0;
4342   unsigned int shortest_trail_index = 0;
4343   int shortest_trail_length = -1;
4344   struct Trail_Element *trail_element;
4345   struct GNUNET_PeerIdentity *trail_list;
4346   unsigned int i;
4347
4348   trail = GNUNET_new (struct Trail);
4349
4350   /* Get the shortest trail to reach to current successor. */
4351   for (i = 0; i < finger->trails_count; i++)
4352   {
4353     trail = &finger->trail_list[i];
4354
4355     if (0 == flag)
4356     {
4357       shortest_trail_index = i;
4358       shortest_trail_length = trail->trail_length;
4359       flag = 1;
4360       continue;
4361     }
4362
4363     if (shortest_trail_length > trail->trail_length)
4364     {
4365       shortest_trail_index = i;
4366       shortest_trail_length = trail->trail_length;
4367     }
4368     continue;
4369   }
4370
4371   /* Copy the shortest trail and return. */
4372   trail = &finger->trail_list[shortest_trail_index];
4373   trail_element = trail->trail_head;
4374
4375   trail_list = GNUNET_malloc (sizeof(struct GNUNET_PeerIdentity)*
4376                               shortest_trail_length);
4377
4378   for(i = 0; i < shortest_trail_length; i++,trail_element = trail_element->next)
4379   {
4380     trail_list[i] = trail_element->peer;
4381   }
4382
4383   GNUNET_assert(shortest_trail_length != -1);
4384
4385   *trail_length = shortest_trail_length;
4386   return trail_list;
4387 }
4388
4389
4390 /**
4391  * Check if trail_1 and trail_2 have any common element. If yes then join 
4392  * them at common element. trail_1 always preceeds trail_2 in joined trail. 
4393  * @param trail_1 Trail from source to me, NOT including endpoints.
4394  * @param trail_1_len Total number of peers @a trail_1
4395  * @param trail_2 Trail from me to current predecessor, NOT including endpoints.
4396  * @param trail_2_len Total number of peers @a trail_2
4397  * @param joined_trail_len Total number of peers in combined trail of trail_1
4398  *                          trail_2.
4399  * @return Joined trail.
4400  */
4401 static struct GNUNET_PeerIdentity *
4402 check_for_duplicate_entries (const struct GNUNET_PeerIdentity *trail_1,
4403                              unsigned int trail_1_len,
4404                              struct GNUNET_PeerIdentity *trail_2,
4405                              unsigned int trail_2_len,
4406                              unsigned int *joined_trail_len)
4407 {
4408   struct GNUNET_PeerIdentity *joined_trail;
4409   unsigned int i;
4410   unsigned int j;
4411   unsigned int k;
4412   
4413   for (i = 0; i < trail_1_len; i++)
4414   {
4415     for (j = 0; j < trail_2_len; j++)
4416     {
4417       if(0 != GNUNET_CRYPTO_cmp_peer_identity (&trail_1[i],&trail_2[j]))
4418         continue;
4419       
4420       *joined_trail_len = i + (trail_2_len - j) + 1;
4421       joined_trail = GNUNET_malloc (*joined_trail_len * 
4422                                     sizeof(struct GNUNET_PeerIdentity));
4423       
4424       
4425       /* Copy all the elements from 0 to i into joined_trail. */
4426       for(k = 0; k < (i+1); k++)
4427       {
4428         joined_trail[k] = trail_1[k];
4429       }
4430       
4431       /* Increment j as entry stored is same as entry stored at i*/
4432       j = j+1;
4433       
4434       /* Copy all the elements from j+1 to trail_2_len-1 to joined trail.*/
4435       while((k < *joined_trail_len) && (j < trail_2_len));
4436       {
4437         joined_trail[k] = trail_2[j];
4438         j++;
4439         k++;
4440       }
4441       
4442       return joined_trail;
4443     }
4444   }
4445  
4446   /* Here you should join the  trails. */
4447   *joined_trail_len = trail_1_len + trail_2_len + 1;
4448   joined_trail = GNUNET_malloc (*joined_trail_len * 
4449                                 sizeof(struct GNUNET_PeerIdentity));
4450   i = 0;
4451   while( i < trail_1_len)
4452   {
4453     joined_trail[i] = trail_1[i];
4454     i++;
4455   }
4456   joined_trail[i] = my_identity;
4457   i++;
4458   
4459   for (j = 0; i < *joined_trail_len; i++,j++)
4460   {
4461     joined_trail[i] = trail_2[j];
4462   }
4463   return joined_trail;
4464 }
4465
4466
4467 /**
4468  * Return the trail from source to my current predecessor. Check if source
4469  * is already part of the this trail, if yes then return the shorten trail.
4470  * @param current_trail Trail from source to me, NOT including the endpoints.
4471  * @param current_trail_length Number of peers in @a current_trail.
4472  * @param trail_src_to_curr_pred_length[out] Number of peers in trail from
4473  *                                           source to my predecessor, NOT including
4474  *                                           the endpoints.
4475  * @return Trail from source to my predecessor.
4476  */
4477 static struct GNUNET_PeerIdentity *
4478 get_trail_src_to_curr_pred (struct GNUNET_PeerIdentity source_peer,
4479                             const struct GNUNET_PeerIdentity *trail_src_to_me,
4480                             unsigned int trail_src_to_me_len,
4481                             unsigned int *trail_src_to_curr_pred_length)
4482 {
4483   struct GNUNET_PeerIdentity *trail_me_to_curr_pred;
4484   struct GNUNET_PeerIdentity *trail_src_to_curr_pred;
4485   unsigned int trail_me_to_curr_pred_length;
4486   struct FingerInfo *current_predecessor;
4487   unsigned int i;
4488   unsigned int j;
4489
4490   current_predecessor = &finger_table[PREDECESSOR_FINGER_ID];
4491   trail_me_to_curr_pred = get_shortest_trail (current_predecessor,
4492                                               &trail_me_to_curr_pred_length);
4493
4494   /* If there is only on element in the trail, and that element is source.*/
4495   if ((trail_me_to_curr_pred_length == 1) && 
4496      (0 == GNUNET_CRYPTO_cmp_peer_identity (&source_peer,
4497                                             &trail_me_to_curr_pred[0])))
4498   {
4499     *trail_src_to_curr_pred_length = 0;
4500     GNUNET_free_non_null(trail_me_to_curr_pred);
4501     return NULL;
4502   }
4503   
4504   /* Check if trail_me_to_curr_pred contains source. */
4505   if (trail_me_to_curr_pred_length > 1)
4506   {
4507     for(i = trail_me_to_curr_pred_length - 1; i > 0; i--)
4508     {
4509       if(0 != GNUNET_CRYPTO_cmp_peer_identity (&source_peer,
4510                                                &trail_me_to_curr_pred[i]))
4511         continue;
4512
4513        /* Source is NOT part of trail. */
4514        i = i+1;
4515
4516       /* Source is the last element in the trail to reach to my pred.
4517          Source is direct friend of the pred. */
4518       if (trail_me_to_curr_pred_length == i)
4519       {
4520         *trail_src_to_curr_pred_length = 0;
4521         return NULL;
4522       }
4523       
4524       *trail_src_to_curr_pred_length = trail_me_to_curr_pred_length - i;
4525       trail_src_to_curr_pred = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)*
4526                                               *trail_src_to_curr_pred_length);
4527       for(j = 0; j < *trail_src_to_curr_pred_length; i++,j++)
4528       {
4529         trail_src_to_curr_pred[j] = trail_me_to_curr_pred[i];
4530       }
4531       GNUNET_free_non_null(trail_me_to_curr_pred);
4532       return trail_src_to_curr_pred;
4533     }
4534     /* Is first element source? Then exclude first element and copy rest of the
4535      trail. */
4536     if(0 == GNUNET_CRYPTO_cmp_peer_identity (&source_peer,
4537                                              &trail_me_to_curr_pred[0]))
4538     {
4539       *trail_src_to_curr_pred_length = trail_me_to_curr_pred_length - 1;
4540       trail_src_to_curr_pred = GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity)*
4541                                              *trail_src_to_curr_pred_length);
4542       unsigned int j;
4543       for(j=0; j < *trail_src_to_curr_pred_length;j++)
4544       {
4545         trail_src_to_curr_pred[j] = trail_me_to_curr_pred[j+1];
4546       }
4547       return trail_src_to_curr_pred;
4548     }
4549   }
4550   
4551   unsigned int len;
4552   trail_src_to_curr_pred = check_for_duplicate_entries (trail_src_to_me, 
4553                                                         trail_src_to_me_len,
4554                                                         trail_me_to_curr_pred,
4555                                                         trail_me_to_curr_pred_length,
4556                                                         &len); 
4557   *trail_src_to_curr_pred_length = len;
4558   GNUNET_free_non_null(trail_me_to_curr_pred);
4559   return trail_src_to_curr_pred;
4560 }
4561
4562
4563 /**
4564  * Add finger as your predecessor. To add, first generate a new trail id, invert
4565  * the trail to get the trail from me to finger, add an entry in your routing
4566  * table, send add trail message to peers which are part of trail from me to
4567  * finger and add finger in finger table.
4568  * @param finger
4569  * @param trail
4570  * @param trail_length
4571  */
4572 static void
4573 update_predecessor (struct GNUNET_PeerIdentity finger,
4574                     struct GNUNET_PeerIdentity *trail,
4575                     unsigned int trail_length)
4576 {
4577   struct GNUNET_HashCode trail_to_new_predecessor_id;
4578   struct GNUNET_PeerIdentity *trail_to_new_predecessor;
4579   struct FriendInfo *target_friend;
4580
4581   /* Generate trail id for trail from me to new predecessor = finger. */
4582   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG,
4583                               &trail_to_new_predecessor_id,
4584                               sizeof (trail_to_new_predecessor_id));
4585
4586   /* Finger is a friend. */
4587   if (trail_length == 0)
4588   {
4589     trail_to_new_predecessor = NULL;
4590     GDS_ROUTING_add (trail_to_new_predecessor_id, my_identity, finger);
4591     GNUNET_assert (NULL != (target_friend =
4592                             GNUNET_CONTAINER_multipeermap_get (friend_peermap,
4593                                                                &finger)));
4594   }
4595   else
4596   {
4597     /* Invert the trail to get the trail from me to finger, NOT including the
4598        endpoints.*/
4599     GNUNET_assert(NULL != GNUNET_CONTAINER_multipeermap_get(friend_peermap,
4600                                                             &trail[trail_length-1]));
4601   
4602     trail_to_new_predecessor = invert_trail (trail, trail_length);
4603     
4604     /* Add an entry in your routing table. */
4605     GDS_ROUTING_add (trail_to_new_predecessor_id,
4606                      my_identity,
4607                      trail_to_new_predecessor[0]);
4608
4609     GNUNET_assert (NULL != (target_friend =
4610                    GNUNET_CONTAINER_multipeermap_get (friend_peermap,
4611                                                       &trail_to_new_predecessor[0])));
4612     GNUNET_assert (NULL != (
4613                    GNUNET_CONTAINER_multipeermap_get (friend_peermap,
4614                                                       &trail[trail_length - 1])));
4615   }
4616
4617   /* Add entry in routing table of all peers that are part of trail from me
4618      to finger, including finger. */
4619   GDS_NEIGHBOURS_send_add_trail (my_identity,
4620                                  finger,
4621                                  trail_to_new_predecessor_id,
4622                                  trail_to_new_predecessor,
4623                                  trail_length,
4624                                  target_friend);
4625
4626   add_new_finger (finger, trail_to_new_predecessor, trail_length,
4627                   trail_to_new_predecessor_id, PREDECESSOR_FINGER_ID);
4628   GNUNET_free_non_null(trail_to_new_predecessor);
4629 }
4630
4631
4632 /*
4633  * Check if you already have a predecessor. If not then add finger as your
4634  * predecessor. If you have predecessor, then compare two peer identites.
4635  * If finger is correct predecessor, then remove the old entry, add finger in
4636  * finger table and send add_trail message to add the trail in the routing
4637  * table of all peers which are part of trail to reach from me to finger.
4638  * @param finger New peer which may be our predecessor.
4639  * @param trail List of peers to reach from @finger to me.
4640  * @param trail_length Total number of peer in @a trail.
4641  */
4642 static void
4643 compare_and_update_predecessor (struct GNUNET_PeerIdentity finger,
4644                                 struct GNUNET_PeerIdentity *trail,
4645                                 unsigned int trail_length)
4646 {
4647   struct FingerInfo *current_predecessor;
4648   const struct GNUNET_PeerIdentity *closest_peer;
4649   uint64_t predecessor_value;
4650   unsigned int is_predecessor = 1;
4651
4652   current_predecessor = &finger_table[PREDECESSOR_FINGER_ID];
4653
4654   GNUNET_assert (0 != GNUNET_CRYPTO_cmp_peer_identity (&finger, &my_identity));
4655
4656   /* No predecessor. Add finger as your predecessor. */
4657   if (GNUNET_NO == current_predecessor->is_present)
4658   {
4659     update_predecessor (finger, trail, trail_length);
4660     return;
4661   }
4662   
4663   if (0 == GNUNET_CRYPTO_cmp_peer_identity (&current_predecessor->finger_identity,
4664                                             &finger))
4665   {
4666     return;
4667   }
4668
4669   predecessor_value = compute_finger_identity_value (PREDECESSOR_FINGER_ID);
4670   closest_peer = select_closest_peer (&finger,
4671                                       &current_predecessor->finger_identity,
4672                                       predecessor_value, is_predecessor);
4673
4674   /* Finger is the closest predecessor. Remove the existing one and add the new
4675      one. */
4676   if (closest_peer == &finger)
4677   {
4678     remove_existing_finger (current_predecessor, PREDECESSOR_FINGER_ID);
4679     update_predecessor (finger, trail, trail_length);
4680     return;
4681   }
4682   return;
4683 }
4684
4685
4686 /*
4687  * Core handle for p2p verify successor messages.
4688  * @param cls closure
4689  * @param message message
4690  * @param peer peer identity this notification is about
4691  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
4692  */
4693 static int
4694 handle_dht_p2p_verify_successor(void *cls,
4695                                 const struct GNUNET_PeerIdentity *peer,
4696                                 const struct GNUNET_MessageHeader *message)
4697 {
4698   const struct PeerVerifySuccessorMessage *vsm;
4699   struct GNUNET_HashCode trail_id;
4700   struct GNUNET_PeerIdentity successor;
4701   struct GNUNET_PeerIdentity source_peer;
4702   struct GNUNET_PeerIdentity *trail;
4703   struct GNUNET_PeerIdentity *next_hop;
4704   struct FingerInfo current_predecessor;
4705   struct FriendInfo *target_friend;
4706   unsigned int trail_src_to_curr_pred_len = 0;
4707   struct GNUNET_PeerIdentity *trail_src_to_curr_pred;
4708   unsigned int trail_length;
4709   size_t msize;
4710   
4711   msize = ntohs (message->size);
4712
4713   if (msize < sizeof (struct PeerVerifySuccessorMessage))
4714   {
4715     GNUNET_break_op (0);
4716     return GNUNET_YES;
4717   }
4718
4719   vsm = (const struct PeerVerifySuccessorMessage *) message;
4720   trail_length = (msize - sizeof (struct PeerVerifySuccessorMessage))/
4721                   sizeof (struct GNUNET_PeerIdentity);
4722   if ((msize - sizeof (struct PeerVerifySuccessorMessage)) %
4723       sizeof (struct GNUNET_PeerIdentity) != 0)
4724   {
4725     GNUNET_break_op (0);
4726     return GNUNET_OK;
4727   }
4728   
4729   GNUNET_STATISTICS_update (GDS_stats,
4730                             gettext_noop
4731                             ("# Bytes received from other peers"), msize,
4732                             GNUNET_NO);
4733   
4734   trail_id = vsm->trail_id;
4735   source_peer = vsm->source_peer;
4736   successor = vsm->successor;
4737   trail = (struct GNUNET_PeerIdentity *)&vsm[1];
4738  
4739
4740   /* I am NOT the successor of source_peer. Pass the message to next_hop on
4741    * the trail. */
4742   if(0 != (GNUNET_CRYPTO_cmp_peer_identity (&successor, &my_identity)))
4743   {
4744     next_hop = GDS_ROUTING_get_next_hop (trail_id, GDS_ROUTING_SRC_TO_DEST);    
4745     if (NULL == next_hop)
4746     {
4747       GNUNET_break_op (0);
4748       return GNUNET_SYSERR;
4749     }
4750
4751     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
4752     
4753     if(NULL == target_friend)
4754     {
4755       GNUNET_break_op(0);
4756       return GNUNET_OK;
4757     }
4758     GDS_NEIGHBOURS_send_verify_successor_message (source_peer, successor,
4759                                                   trail_id, trail, trail_length,
4760                                                   target_friend);
4761     return GNUNET_OK;
4762   }
4763
4764   /* I am the destination of this message. */
4765
4766   /* Check if the source_peer could be our predecessor and if yes then update
4767    * it.  */
4768   compare_and_update_predecessor (source_peer, trail, trail_length);
4769   current_predecessor = finger_table[PREDECESSOR_FINGER_ID];
4770   unsigned int flag = 0;
4771   
4772   /* Is source of this message NOT my predecessor. */
4773   if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&current_predecessor.finger_identity,
4774                                              &source_peer)))
4775   {
4776     /* Check if trail contains current_predecessor. */
4777     unsigned int i;
4778     for (i = 0; i < trail_length; i++)
4779     {
4780       if(0 != GNUNET_CRYPTO_cmp_peer_identity(&trail[i],
4781                                               &current_predecessor.finger_identity))
4782         continue;
4783       
4784       flag = 1;
4785       trail_src_to_curr_pred_len = i;
4786       trail_src_to_curr_pred = GNUNET_malloc (trail_src_to_curr_pred_len *
4787                                               sizeof(struct GNUNET_PeerIdentity));
4788       unsigned int k = 0;
4789       
4790       while(k < i)
4791       {
4792         trail_src_to_curr_pred[k] = trail[k];
4793         k++;
4794       }
4795       break;
4796     }
4797  
4798     if(0 == flag)
4799     {
4800       trail_src_to_curr_pred = 
4801               get_trail_src_to_curr_pred (source_peer,
4802                                           trail,
4803                                           trail_length,
4804                                           &trail_src_to_curr_pred_len);
4805     }
4806   }
4807   else
4808   {
4809     trail_src_to_curr_pred_len = trail_length;
4810     unsigned int i;
4811
4812     trail_src_to_curr_pred = 
4813             GNUNET_malloc (sizeof(struct GNUNET_PeerIdentity)
4814                            *trail_src_to_curr_pred_len);
4815     for(i = 0; i < trail_src_to_curr_pred_len; i++)
4816     {
4817       trail_src_to_curr_pred[i] = trail[i];
4818     }
4819   }
4820  
4821   GNUNET_assert (NULL !=
4822                 (target_friend =
4823                  GNUNET_CONTAINER_multipeermap_get (friend_peermap, peer)));
4824   GDS_NEIGHBOURS_send_verify_successor_result (source_peer, my_identity,
4825                                                current_predecessor.finger_identity,
4826                                                trail_id, trail_src_to_curr_pred,
4827                                                trail_src_to_curr_pred_len,
4828                                                GDS_ROUTING_DEST_TO_SRC,
4829                                                target_friend);
4830   GNUNET_free_non_null(trail_src_to_curr_pred);
4831   return GNUNET_OK;
4832 }
4833
4834
4835 /**
4836  * If the trail from me to my probable successor contains a friend not
4837  * at index 0, then we can shorten the trail.
4838  * @param probable_successor Peer which is our probable successor
4839  * @param trail_me_to_probable_successor Peers in path from me to my probable
4840  *                                       successor, NOT including the endpoints.
4841  * @param trail_me_to_probable_successor_len Total number of peers in
4842  *                                           @a trail_me_to_probable_succesor.
4843  * @return Updated trail, if any friend found.
4844  *         Else the trail_me_to_probable_successor.
4845  */
4846 struct GNUNET_PeerIdentity *
4847 check_trail_me_to_probable_succ (struct GNUNET_PeerIdentity probable_successor,
4848                                  const struct GNUNET_PeerIdentity *trail_me_to_probable_successor,
4849                                  unsigned int trail_me_to_probable_successor_len,
4850                                  unsigned int *trail_to_new_successor_length)
4851 {
4852   unsigned int i;
4853   unsigned int j;
4854   struct GNUNET_PeerIdentity *trail_to_new_successor;
4855
4856   /* Probable successor is  a friend */
4857   if (NULL != GNUNET_CONTAINER_multipeermap_get (friend_peermap,
4858                                                  &probable_successor))
4859   {
4860     trail_to_new_successor = NULL;
4861     *trail_to_new_successor_length = 0;
4862     return trail_to_new_successor;
4863   }
4864   
4865   /* Is there any friend of yours in this trail. */
4866   if(trail_me_to_probable_successor_len > 1)
4867   {
4868     for (i = trail_me_to_probable_successor_len - 1; i > 0; i--)
4869     {
4870       if (NULL == GNUNET_CONTAINER_multipeermap_get (friend_peermap,
4871                                                      &trail_me_to_probable_successor[i]))
4872         continue;
4873
4874       j = 0;
4875       *trail_to_new_successor_length = (trail_me_to_probable_successor_len - i);
4876       trail_to_new_successor = GNUNET_malloc (sizeof(struct GNUNET_PeerIdentity)*
4877                                                 *trail_to_new_successor_length);
4878
4879      
4880       for(j = 0;j < *trail_to_new_successor_length;i++,j++)
4881       {
4882         trail_to_new_successor[j] = trail_me_to_probable_successor[i];
4883       }
4884       
4885       return trail_to_new_successor;
4886     }
4887   }
4888
4889   *trail_to_new_successor_length = trail_me_to_probable_successor_len;
4890   return (struct GNUNET_PeerIdentity*)trail_me_to_probable_successor;
4891 #if 0
4892   trail_to_new_successor = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)*
4893                                           *trail_to_new_successor_length);
4894
4895   for(i = 0; i < *trail_to_new_successor_length; i++)
4896     trail_to_new_successor[i] = trail_me_to_probable_successor[i];
4897
4898   return trail_to_new_successor;
4899 #endif
4900 }
4901
4902
4903 /**
4904  * Check if the peer which sent us verify successor result message is still ours
4905  * successor or not. If not, then compare existing successor and probable successor.
4906  * In case probable successor is the correct successor, remove the existing
4907  * successor. Add probable successor as new successor. Send notify new successor
4908  * message to new successor.
4909  * @param curr_succ
4910  * @param probable_successor
4911  * @param trail
4912  * @param trail_length
4913  */
4914 static void
4915 compare_and_update_successor (struct GNUNET_PeerIdentity curr_succ,
4916                               struct GNUNET_PeerIdentity probable_successor,
4917                               const struct GNUNET_PeerIdentity *trail,
4918                               unsigned int trail_length)
4919 {
4920   struct FingerInfo *current_successor;
4921   const struct GNUNET_PeerIdentity *closest_peer;
4922   struct GNUNET_HashCode trail_id;
4923   struct GNUNET_PeerIdentity *trail_me_to_probable_succ;
4924   struct FriendInfo *target_friend;
4925   unsigned int trail_me_to_probable_succ_len;
4926   unsigned int is_predecessor = GNUNET_NO;
4927   uint64_t successor_value;
4928
4929   current_successor = &finger_table[0];
4930   successor_value = compute_finger_identity_value(0);
4931
4932   /* Have we found some other successor, while waiting for verify successor result
4933    *
4934    * FIXME closest_peer is being overwritten just after the if
4935    */
4936 #if 0
4937   if(0 != GNUNET_CRYPTO_cmp_peer_identity(&curr_succ, &current_successor->finger_identity))
4938   {
4939     /* We could have added this new successor, only if it was closer the old one. */
4940     closest_peer = select_closest_peer (&curr_succ,
4941                                         &current_successor->finger_identity,
4942                                         successor_value, is_predecessor);
4943
4944     /* FIXME: it may fail in case we have done more number of iterations of
4945      find _finger_trail_task. */
4946     /*GNUNET_assert (0 ==
4947                    GNUNET_CRYPTO_cmp_peer_identity (closest_peer,
4948                                                     &current_successor->finger_identity));*/
4949
4950   }
4951 #endif
4952
4953   closest_peer = select_closest_peer (&probable_successor,
4954                                       &current_successor->finger_identity,
4955                                       successor_value, is_predecessor);
4956
4957   /* If the current_successor in the finger table is closest, then do nothing. */
4958   if (closest_peer == &current_successor->finger_identity)
4959     return;
4960
4961   /* Probable successor is the closest peer.*/
4962   if(trail_length > 0)
4963   {
4964     GNUNET_assert(NULL != GNUNET_CONTAINER_multipeermap_get(friend_peermap,
4965                                                             &trail[0]));
4966   }
4967   else
4968   {
4969     GNUNET_assert(NULL != GNUNET_CONTAINER_multipeermap_get(friend_peermap,
4970                                                             &probable_successor));
4971   }
4972   
4973   trail_me_to_probable_succ_len = 0;
4974   /* TODO: Check if the path to reach to probable successor contains a friend. */
4975   trail_me_to_probable_succ =
4976           check_trail_me_to_probable_succ (probable_successor,
4977                                            trail, trail_length,
4978                                            &trail_me_to_probable_succ_len);
4979
4980   /* Remove the existing successor. */
4981   remove_existing_finger (current_successor, 0);
4982
4983   /* TODO URGENT: Check if any peer is present more than once, if yes then shorten
4984    the trail. before sending it across the network. */
4985    /* Generate a new trail id to reach to your new successor. */
4986   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG,
4987                               &trail_id, sizeof (trail_id));
4988
4989   if (trail_me_to_probable_succ_len > 0)
4990   {
4991     GDS_ROUTING_add (trail_id, my_identity, trail_me_to_probable_succ[0]);
4992     GNUNET_assert (NULL !=
4993                   (target_friend =
4994                       GNUNET_CONTAINER_multipeermap_get (friend_peermap,
4995                                                         &trail_me_to_probable_succ[0])));
4996   }
4997   else
4998   {
4999     GDS_ROUTING_add (trail_id, my_identity, probable_successor);
5000     GNUNET_assert (NULL !=
5001                   (target_friend =
5002                    GNUNET_CONTAINER_multipeermap_get (friend_peermap,
5003                                                       &probable_successor)));
5004   }
5005
5006   add_new_finger (probable_successor, trail_me_to_probable_succ,
5007                   trail_me_to_probable_succ_len, trail_id, 0);
5008  
5009   GDS_NEIGHBOURS_send_notify_new_successor (my_identity, probable_successor,
5010                                             trail_me_to_probable_succ,
5011                                             trail_me_to_probable_succ_len,
5012                                             trail_id,
5013                                             target_friend);
5014   return;
5015 }
5016
5017
5018 /*
5019  * FIXME: Check for duplicate elements everywhere when you are making
5020  * trails. 
5021  * Core handle for p2p verify successor result messages.
5022  * @param cls closure
5023  * @param message message
5024  * @param peer peer identity this notification is about
5025  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
5026  */
5027 static int
5028 handle_dht_p2p_verify_successor_result(void *cls,
5029                                        const struct GNUNET_PeerIdentity *peer,
5030                                        const struct GNUNET_MessageHeader *message)
5031 {
5032   const struct PeerVerifySuccessorResultMessage *vsrm;
5033   enum GDS_ROUTING_trail_direction trail_direction;
5034   struct GNUNET_PeerIdentity querying_peer;
5035   struct GNUNET_HashCode trail_id;
5036   struct GNUNET_PeerIdentity *next_hop;
5037   struct FriendInfo *target_friend;
5038   struct GNUNET_PeerIdentity probable_successor;
5039   struct GNUNET_PeerIdentity current_successor;
5040   const struct GNUNET_PeerIdentity *trail;
5041   unsigned int trail_length;
5042   size_t msize;
5043
5044   msize = ntohs (message->size);
5045   /* We send a trail to reach from old successor to new successor, if
5046    * old_successor != new_successor.*/
5047   if (msize < sizeof (struct PeerVerifySuccessorResultMessage))
5048   {
5049     GNUNET_break_op (0);
5050     return GNUNET_YES;
5051   }
5052
5053   vsrm = (const struct PeerVerifySuccessorResultMessage *) message;
5054   trail_length = (msize - sizeof (struct PeerVerifySuccessorResultMessage))/
5055                       sizeof (struct GNUNET_PeerIdentity);
5056
5057   if ((msize - sizeof (struct PeerVerifySuccessorResultMessage)) %
5058       sizeof (struct GNUNET_PeerIdentity) != 0)
5059   {
5060     GNUNET_break_op (0);
5061     return GNUNET_OK;
5062   }
5063
5064   GNUNET_STATISTICS_update (GDS_stats,
5065                             gettext_noop
5066                             ("# Bytes received from other peers"), msize,
5067                             GNUNET_NO);
5068   
5069   trail = (const struct GNUNET_PeerIdentity *) &vsrm[1];
5070   querying_peer = vsrm->querying_peer;
5071   trail_direction = ntohl (vsrm->trail_direction);
5072   trail_id = vsrm->trail_id;
5073   probable_successor = vsrm->probable_successor;
5074   current_successor = vsrm->current_successor;
5075  
5076
5077   /* I am the querying_peer. */
5078   if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&querying_peer, &my_identity)))
5079   {
5080     compare_and_update_successor (current_successor,
5081                                   probable_successor, trail, trail_length);
5082     return GNUNET_OK;
5083   }
5084   
5085   /*If you are not the querying peer then pass on the message */
5086   GNUNET_assert (NULL != (next_hop =
5087                          GDS_ROUTING_get_next_hop (trail_id, trail_direction)));
5088   GNUNET_assert (NULL !=
5089                 (target_friend =
5090                  GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop)));
5091   GDS_NEIGHBOURS_send_verify_successor_result (querying_peer,
5092                                                vsrm->current_successor,
5093                                                probable_successor, trail_id,
5094                                                trail,
5095                                                trail_length,
5096                                                trail_direction, target_friend);
5097   return GNUNET_OK;
5098 }
5099
5100
5101 /*
5102  * Core handle for p2p notify new successor messages.
5103  * @param cls closure
5104  * @param message message
5105  * @param peer peer identity this notification is about
5106  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
5107  */
5108 static int
5109 handle_dht_p2p_notify_new_successor(void *cls,
5110                                     const struct GNUNET_PeerIdentity *peer,
5111                                     const struct GNUNET_MessageHeader *message)
5112 {
5113   const struct PeerNotifyNewSuccessorMessage *nsm;
5114   struct GNUNET_PeerIdentity *trail;
5115   struct GNUNET_PeerIdentity source;
5116   struct GNUNET_PeerIdentity new_successor;
5117   struct GNUNET_HashCode trail_id;
5118   struct GNUNET_PeerIdentity next_hop;
5119   struct FriendInfo *target_friend;
5120   int my_index;
5121   size_t msize;
5122   uint32_t trail_length;
5123
5124   msize = ntohs (message->size);
5125
5126   /* We have the trail to reach from source to new successor. */
5127   if (msize < sizeof (struct PeerNotifyNewSuccessorMessage))
5128   {
5129     GNUNET_break_op (0);
5130     return GNUNET_YES;
5131   }
5132
5133   nsm = (const struct PeerNotifyNewSuccessorMessage *) message;
5134   trail_length = (msize - sizeof (struct PeerNotifyNewSuccessorMessage))/
5135                   sizeof (struct GNUNET_PeerIdentity);
5136   if ((msize - sizeof (struct PeerNotifyNewSuccessorMessage)) %
5137       sizeof (struct GNUNET_PeerIdentity) != 0)
5138   {
5139     GNUNET_break_op (0);
5140     return GNUNET_OK;
5141   }
5142
5143   GNUNET_STATISTICS_update (GDS_stats,
5144                             gettext_noop
5145                             ("# Bytes received from other peers"), msize,
5146                             GNUNET_NO);
5147   
5148   trail = (struct GNUNET_PeerIdentity *) &nsm[1];
5149   source  = nsm->source_peer;
5150   new_successor = nsm->new_successor;
5151   trail_id = nsm->trail_id;
5152   
5153
5154   //FIXME: add a check to make sure peer is correct.
5155
5156   /* I am the new_successor to source_peer. */
5157   if ( 0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &new_successor))
5158   {
5159     if(trail_length > 0)
5160       GNUNET_assert(0 == GNUNET_CRYPTO_cmp_peer_identity(&trail[trail_length - 1],
5161                                                           peer));
5162     else 
5163       GNUNET_assert(0 == GNUNET_CRYPTO_cmp_peer_identity(&source, peer));
5164   
5165     compare_and_update_predecessor (source, trail, trail_length);
5166     return GNUNET_OK;
5167   }
5168
5169   GNUNET_assert(trail_length > 0);
5170   /* I am part of trail to reach to successor. */
5171   my_index = search_my_index (trail, trail_length);
5172   if (-1 == my_index)
5173   {
5174     GNUNET_break_op (0);
5175     return GNUNET_SYSERR;
5176   }
5177
5178   if ((trail_length-1) == my_index)
5179     next_hop = new_successor;
5180   else
5181     next_hop = trail[my_index + 1];
5182
5183
5184   /* Add an entry in routing table for trail from source to its new successor. */
5185   GNUNET_assert (GNUNET_OK == GDS_ROUTING_add (trail_id, *peer, next_hop));
5186   GNUNET_assert (NULL !=
5187                 (target_friend =
5188                  GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop)));
5189   GDS_NEIGHBOURS_send_notify_new_successor (source, new_successor, trail,
5190                                             trail_length,
5191                                             trail_id, target_friend);
5192   return GNUNET_OK;
5193
5194 }
5195
5196
5197 /**
5198  * Core handler for P2P trail rejection message
5199  * @param cls closure
5200  * @param message message
5201  * @param peer peer identity this notification is about
5202  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
5203  */
5204 static int
5205 handle_dht_p2p_trail_setup_rejection (void *cls,
5206                                       const struct GNUNET_PeerIdentity *peer,
5207                                       const struct GNUNET_MessageHeader *message)
5208 {
5209   const struct PeerTrailRejectionMessage *trail_rejection;
5210   unsigned int trail_length;
5211   const struct GNUNET_PeerIdentity *trail_peer_list;
5212   struct FriendInfo *target_friend;
5213   struct GNUNET_TIME_Relative congestion_timeout;
5214   struct GNUNET_HashCode trail_id;
5215   struct GNUNET_PeerIdentity next_peer;
5216   struct GNUNET_PeerIdentity source;
5217   struct GNUNET_PeerIdentity *next_hop;
5218   uint64_t ultimate_destination_finger_value;
5219   unsigned int is_predecessor;
5220   size_t msize;
5221
5222   msize = ntohs (message->size);
5223   /* We are passing the trail setup so far. */
5224   if (msize < sizeof (struct PeerTrailRejectionMessage))
5225   {
5226     GNUNET_break_op (0);
5227     return GNUNET_YES;
5228   }
5229
5230   trail_rejection = (const struct PeerTrailRejectionMessage *) message;
5231   trail_length = (msize - sizeof (struct PeerTrailRejectionMessage))/
5232                   sizeof (struct GNUNET_PeerIdentity);
5233   if ((msize - sizeof (struct PeerTrailRejectionMessage)) %
5234       sizeof (struct GNUNET_PeerIdentity) != 0)
5235   {
5236     GNUNET_break_op (0);
5237     return GNUNET_OK;
5238   }
5239   
5240   GNUNET_STATISTICS_update (GDS_stats,
5241                             gettext_noop
5242                             ("# Bytes received from other peers"), msize,
5243                             GNUNET_NO);
5244   
5245   trail_peer_list = (const struct GNUNET_PeerIdentity *)&trail_rejection[1];
5246   is_predecessor = ntohl (trail_rejection->is_predecessor);
5247   congestion_timeout = trail_rejection->congestion_time;
5248   source = trail_rejection->source_peer;
5249   trail_id = trail_rejection->trail_id;
5250   ultimate_destination_finger_value =
5251           GNUNET_ntohll (trail_rejection->ultimate_destination_finger_value);
5252
5253   /* First set the congestion time of the friend that sent you this message. */
5254   GNUNET_assert (NULL !=
5255                  (target_friend =
5256                   GNUNET_CONTAINER_multipeermap_get (friend_peermap, peer)));
5257   target_friend->congestion_timestamp =
5258           GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(),
5259                                     congestion_timeout);
5260
5261   /* I am the source peer which wants to setup the trail. Do nothing.
5262    * send_find_finger_trail_task is scheduled periodically.*/
5263   if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &source)))
5264     return GNUNET_OK;
5265
5266   /* If I am congested then pass this message to peer before me in trail. */
5267   if(GNUNET_YES == GDS_ROUTING_threshold_reached())
5268   {
5269     struct GNUNET_PeerIdentity *new_trail;
5270     unsigned int new_trail_length;
5271
5272     /* Remove yourself from the trail setup so far. */
5273     if (trail_length == 1)
5274     {
5275       new_trail = NULL;
5276       new_trail_length = 0;
5277       next_hop = &source;
5278     }
5279     else
5280     {
5281       memcpy (&next_hop , &trail_peer_list[trail_length - 2],
5282               sizeof (struct GNUNET_PeerIdentity));
5283
5284       /* Remove myself from the trail. */
5285       new_trail_length = trail_length -1;
5286       new_trail = GNUNET_malloc (new_trail_length * sizeof (struct GNUNET_PeerIdentity));
5287       memcpy (new_trail, trail_peer_list, new_trail_length * sizeof (struct GNUNET_PeerIdentity));
5288     }
5289
5290     GNUNET_assert (NULL !=
5291                   (target_friend =
5292                     GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop)));
5293     GDS_NEIGHBOURS_send_trail_rejection (source,
5294                                          ultimate_destination_finger_value,
5295                                          my_identity, is_predecessor,
5296                                          new_trail,new_trail_length,trail_id,
5297                                          target_friend, CONGESTION_TIMEOUT);
5298     GNUNET_free (new_trail);
5299     return GNUNET_OK;
5300   }
5301
5302   struct Closest_Peer successor;
5303   successor = find_successor (ultimate_destination_finger_value, is_predecessor);
5304
5305   /* Am I the final destination? */
5306   if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&successor.best_known_destination,
5307                                              &my_identity)))
5308   {
5309     if (0 == trail_length)
5310       next_peer = source;
5311     else
5312       next_peer = trail_peer_list[trail_length-1];
5313
5314     GNUNET_assert (NULL !=
5315                   (target_friend =
5316                    GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_peer)));
5317
5318     GDS_NEIGHBOURS_send_trail_setup_result (source,
5319                                             my_identity,
5320                                             target_friend, trail_length,
5321                                             trail_peer_list,
5322                                             is_predecessor,
5323                                             ultimate_destination_finger_value,
5324                                             trail_id);
5325   }
5326   else
5327   {
5328     struct GNUNET_PeerIdentity peer_list[trail_length + 1];
5329
5330     memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
5331     peer_list[trail_length] = my_identity;
5332
5333     GNUNET_assert (NULL !=
5334                   (target_friend =
5335                    GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop)));
5336
5337     GDS_NEIGHBOURS_send_trail_setup (source,
5338                                      ultimate_destination_finger_value,
5339                                      successor.best_known_destination,
5340                                      target_friend, trail_length + 1, peer_list,
5341                                      is_predecessor, trail_id,
5342                                      successor.trail_id);
5343   }
5344   return GNUNET_OK;
5345 }
5346
5347
5348 /*
5349  * Core handle for p2p trail tear compression messages.
5350  * @param cls closure
5351  * @param message message
5352  * @param peer peer identity this notification is about
5353  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
5354  */
5355 static int
5356 handle_dht_p2p_trail_compression (void *cls, const struct GNUNET_PeerIdentity *peer,
5357                                   const struct GNUNET_MessageHeader *message)
5358 {
5359   const struct PeerTrailCompressionMessage *trail_compression;
5360   struct GNUNET_PeerIdentity *next_hop;
5361   struct FriendInfo *target_friend;
5362   struct GNUNET_HashCode trail_id;
5363   size_t msize;
5364
5365   msize = ntohs (message->size);
5366
5367   if (msize != sizeof (struct PeerTrailCompressionMessage))
5368   {
5369     GNUNET_break_op (0);
5370     return GNUNET_OK;
5371   }
5372
5373   GNUNET_STATISTICS_update (GDS_stats,
5374                             gettext_noop
5375                             ("# Bytes received from other peers"), msize,
5376                             GNUNET_NO);
5377   
5378   trail_compression = (const struct PeerTrailCompressionMessage *) message;
5379   trail_id = trail_compression->trail_id;
5380
5381   /* Am I the new first friend to reach to finger of this trail. */
5382   if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&trail_compression->new_first_friend,
5383                                              &my_identity)))
5384   {
5385     GNUNET_assert (NULL !=
5386                   (GNUNET_CONTAINER_multipeermap_get (friend_peermap,
5387                                                       &trail_compression->source_peer)));
5388
5389     /* Update your prev hop to source of this message. */
5390     GNUNET_assert (GNUNET_SYSERR !=
5391                   (GDS_ROUTING_update_trail_prev_hop (trail_id,
5392                                                       trail_compression->source_peer)));
5393     return GNUNET_OK;
5394   }
5395
5396   /* Pass the message to next hop to finally reach to new_first_friend. */
5397   next_hop = GDS_ROUTING_get_next_hop (trail_id, GDS_ROUTING_SRC_TO_DEST);
5398
5399   if (NULL == next_hop)
5400   {
5401     GNUNET_break (0);
5402     return GNUNET_OK;
5403   }
5404
5405   GNUNET_assert (NULL !=
5406                 (target_friend =
5407                  GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop)));
5408
5409   GDS_ROUTING_remove_trail (trail_id);
5410
5411   GDS_NEIGHBOURS_send_trail_compression (trail_compression->source_peer,
5412                                          trail_id,
5413                                          trail_compression->new_first_friend,
5414                                          target_friend);
5415   return GNUNET_OK;
5416 }
5417
5418
5419 /**
5420  * Core handler for trail teardown message.
5421  * @param cls closure
5422  * @param message message
5423  * @param peer sender of this messsage.
5424  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
5425  */
5426 static int
5427 handle_dht_p2p_trail_teardown (void *cls, const struct GNUNET_PeerIdentity *peer,
5428                                const struct GNUNET_MessageHeader *message)
5429 {
5430   const struct PeerTrailTearDownMessage *trail_teardown;
5431   enum GDS_ROUTING_trail_direction trail_direction;
5432   struct GNUNET_HashCode trail_id;
5433   struct GNUNET_PeerIdentity *next_hop;
5434   size_t msize;
5435
5436   msize = ntohs (message->size);
5437
5438   /* Here we pass only the trail id. */
5439   if (msize != sizeof (struct PeerTrailTearDownMessage))
5440   {
5441     GNUNET_break_op (0);
5442     return GNUNET_OK;
5443   }
5444
5445   GNUNET_STATISTICS_update (GDS_stats,
5446                             gettext_noop
5447                             ("# Bytes received from other peers"), msize,
5448                             GNUNET_NO);
5449   
5450   trail_teardown = (const struct PeerTrailTearDownMessage *) message;
5451   trail_direction = ntohl (trail_teardown->trail_direction);
5452   trail_id = trail_teardown->trail_id;
5453
5454   /* Check if peer is the real peer from which we should get this message.*/
5455   /* Get the prev_hop for this trail by getting the next hop in opposite direction. */
5456 #if 0
5457   GNUNET_assert (NULL != (prev_hop =
5458                  GDS_ROUTING_get_next_hop (trail_id, !trail_direction)));
5459   if (0 != GNUNET_CRYPTO_cmp_peer_identity (prev_hop, peer))
5460   {
5461     GNUNET_break (0);
5462     return GNUNET_SYSERR;
5463   }
5464 #endif
5465
5466   next_hop = GDS_ROUTING_get_next_hop (trail_id, trail_direction);
5467
5468   if (NULL == next_hop)
5469   {
5470     GNUNET_break (0);
5471     return GNUNET_SYSERR;
5472   }
5473
5474   /* I am the next hop, which means I am the final destination. */
5475   if (0 == GNUNET_CRYPTO_cmp_peer_identity (next_hop, &my_identity))
5476   {
5477     GNUNET_assert (GNUNET_YES == GDS_ROUTING_remove_trail (trail_id));
5478     return GNUNET_OK;
5479   }
5480   else
5481   {
5482     /* If not final destination, then send a trail teardown message to next hop.*/
5483     GNUNET_assert (NULL != GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop));
5484     GNUNET_assert (GNUNET_YES == GDS_ROUTING_remove_trail (trail_id));
5485     GDS_NEIGHBOURS_send_trail_teardown (trail_id, trail_direction, *next_hop);
5486   }
5487
5488   return GNUNET_OK;
5489 }
5490
5491
5492 /**
5493  * Core handle for p2p add trail message.
5494  * @param cls closure
5495  * @param message message
5496  * @param peer peer identity this notification is about
5497  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
5498  */
5499 static int
5500 handle_dht_p2p_add_trail (void *cls, const struct GNUNET_PeerIdentity *peer,
5501                           const struct GNUNET_MessageHeader *message)
5502 {
5503   const struct PeerAddTrailMessage *add_trail;
5504   const struct GNUNET_PeerIdentity *trail;
5505   struct GNUNET_HashCode trail_id;
5506   struct GNUNET_PeerIdentity destination_peer;
5507   struct GNUNET_PeerIdentity source_peer;
5508   struct GNUNET_PeerIdentity next_hop;
5509   unsigned int trail_length;
5510   unsigned int my_index;
5511   size_t msize;
5512
5513   msize = ntohs (message->size);
5514   /* In this message we pass the whole trail from source to destination as we
5515    * are adding that trail.*/
5516   //FIXME: failed when run with 1000 pears. check why.
5517   if (msize < sizeof (struct PeerAddTrailMessage))
5518   {
5519     GNUNET_break_op (0);
5520     return GNUNET_OK;
5521   }
5522
5523   add_trail = (const struct PeerAddTrailMessage *) message;
5524   trail_length = (msize - sizeof (struct PeerAddTrailMessage))/
5525                   sizeof (struct GNUNET_PeerIdentity);
5526   if ((msize - sizeof (struct PeerAddTrailMessage)) %
5527       sizeof (struct GNUNET_PeerIdentity) != 0)
5528   {
5529     GNUNET_break_op (0);
5530     return GNUNET_OK;
5531   }
5532
5533   GNUNET_STATISTICS_update (GDS_stats,
5534                             gettext_noop
5535                             ("# Bytes received from other peers"), msize,
5536                             GNUNET_NO);
5537   
5538   trail = (const struct GNUNET_PeerIdentity *)&add_trail[1];
5539   destination_peer = add_trail->destination_peer;
5540   source_peer = add_trail->source_peer;
5541   trail_id = add_trail->trail_id;
5542
5543   //FIXME: add a check that sender peer is not malicious. Make it a generic
5544   // function so that it can be used in all other functions where we need the
5545   // same functionality.
5546
5547   /* I am not the destination of the trail. */
5548   if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &destination_peer))
5549   {
5550     struct FriendInfo *target_friend;
5551
5552     /* Get my location in the trail. */
5553     my_index = search_my_index (trail, trail_length);
5554     if (-1 == my_index)
5555     {
5556       GNUNET_break_op (0);
5557       return GNUNET_SYSERR;
5558     }
5559
5560     if ((trail_length - 1) == my_index)
5561     {
5562       next_hop = destination_peer;
5563     }
5564     else
5565     {
5566       next_hop = trail[my_index + 1];
5567     }
5568
5569     /* Add in your routing table. */
5570     GNUNET_assert (GNUNET_OK == GDS_ROUTING_add (trail_id, next_hop, *peer));
5571     GNUNET_assert (NULL !=
5572                   (target_friend =
5573                    GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop)));
5574     GDS_NEIGHBOURS_send_add_trail (source_peer, destination_peer, trail_id,
5575                                    trail, trail_length, target_friend);
5576     return GNUNET_OK;
5577   }
5578   /* I am the destination. Add an entry in routing table. */
5579   GNUNET_assert (GNUNET_OK == GDS_ROUTING_add (trail_id, *peer, my_identity));
5580   return GNUNET_OK;
5581 }
5582
5583
5584 /**
5585  * Free the finger trail in which the first friend to reach to a finger is
5586  * disconnected_friend. Also remove entry from routing table for that particular
5587  * trail id.
5588  * @param disconnected_friend PeerIdentity of friend which got disconnected
5589  * @param remove_finger Finger whose trail we need to check if it has
5590  *                      disconnected_friend as the first hop.
5591  * @return Total number of trails in which disconnected_friend was the first
5592  *         hop.
5593  */
5594 static int
5595 remove_matching_trails (const struct GNUNET_PeerIdentity *disconnected_friend,
5596                         struct FingerInfo *remove_finger)
5597 {
5598   unsigned int matching_trails_count;
5599   int i;
5600
5601   /* Number of trails with disconnected_friend as the first hop in the trail
5602    * to reach from me to remove_finger, NOT including endpoints. */
5603   matching_trails_count = 0;
5604
5605   /* Iterate over all the trails of finger. */
5606   for (i = 0; i < remove_finger->trails_count; i++)
5607   {
5608     struct Trail *trail;
5609     trail = &remove_finger->trail_list[i];
5610
5611     /* This assertion is ensure that there are no gaps in the trail list.
5612      REMOVE IT AFTERWARDS. */
5613     GNUNET_assert (GNUNET_YES == trail->is_present);
5614
5615     /* First friend to reach to finger is disconnected_peer. */
5616     if (0 == GNUNET_CRYPTO_cmp_peer_identity (&trail->trail_head->peer,
5617                                               disconnected_friend))
5618     {
5619       struct GNUNET_PeerIdentity *next_hop;
5620       struct FriendInfo *remove_friend;
5621
5622       GNUNET_assert (NULL !=
5623                     (remove_friend =
5624                      GNUNET_CONTAINER_multipeermap_get (friend_peermap,
5625                                                         disconnected_friend)));
5626       /* FIXME: removing no but check it. */
5627       //remove_friend->trails_count--;
5628       next_hop = GDS_ROUTING_get_next_hop (trail->trail_id,
5629                                            GDS_ROUTING_SRC_TO_DEST);
5630
5631       /* Here it may happen that as all the peers got disconnected, the entry in
5632        routing table for that particular trail has been removed, because the
5633        previously disconnected peer was either a next hop or prev hop of that
5634        peer. */
5635       if (NULL == next_hop)
5636         continue;
5637
5638       GNUNET_assert (0 == (GNUNET_CRYPTO_cmp_peer_identity (disconnected_friend,
5639                                                             next_hop)));
5640       matching_trails_count++;
5641       GNUNET_assert (GNUNET_YES == GDS_ROUTING_remove_trail (trail->trail_id));
5642
5643       free_trail (trail);
5644       trail->is_present = GNUNET_NO;
5645     }
5646   }
5647   return matching_trails_count;
5648 }
5649
5650
5651 /**
5652  * Iterate over finger_table entries.
5653  * 0. Ignore finger which is my_identity or if no valid entry present at
5654  *    that finger index.
5655  * 1. If disconnected_friend is a finger, then remove the routing entry from
5656       your own table. Free the trail.
5657  * 2. Check if disconnected_friend is the first friend in the trail to reach to a finger.
5658  *   2.1 Remove all the trails and entry from routing table in which disconnected
5659  *       friend is the first friend in the trail. If disconnected_friend is the
5660  *       first friend in all the trails to reach finger, then remove the finger.
5661  * @param disconnected_friend Peer identity of friend which got disconnected.
5662  */
5663 static void
5664 remove_matching_fingers (const struct GNUNET_PeerIdentity *disconnected_peer)
5665 {
5666   struct FingerInfo *remove_finger;
5667   struct FriendInfo *remove_friend;
5668   int removed_trails_count;
5669   int i;
5670
5671   /* Iterate over finger table entries. */
5672   for (i = 0; i < MAX_FINGERS; i++)
5673   {
5674     remove_finger = &finger_table[i];
5675
5676     /* No finger stored at this trail index. */
5677     if (GNUNET_NO == remove_finger->is_present)
5678       continue;
5679
5680     /* I am my own finger, then ignore this finger. */
5681     if (0 == GNUNET_CRYPTO_cmp_peer_identity (&remove_finger->finger_identity,
5682                                               &my_identity))
5683       continue;
5684
5685     /* Is disconnected_peer a finger? */
5686     if (0 == GNUNET_CRYPTO_cmp_peer_identity (disconnected_peer,
5687                                               &remove_finger->finger_identity))
5688     {
5689       struct GNUNET_PeerIdentity *next_hop;
5690       struct GNUNET_HashCode trail_id;
5691
5692
5693       GNUNET_assert (GNUNET_YES == (remove_finger->trail_list[0].is_present));
5694       trail_id = remove_finger->trail_list[0].trail_id;
5695
5696       if(NULL !=
5697               (next_hop =
5698                GDS_ROUTING_get_next_hop (trail_id, GDS_ROUTING_SRC_TO_DEST)))
5699       {
5700         GNUNET_assert (0 ==
5701                       (GNUNET_CRYPTO_cmp_peer_identity (next_hop,
5702                                                         &remove_finger->finger_identity)));
5703         GNUNET_assert (GNUNET_YES == GDS_ROUTING_remove_trail (trail_id));
5704         GNUNET_assert (NULL !=
5705                        (remove_friend =
5706                         GNUNET_CONTAINER_multipeermap_get (friend_peermap,
5707                                                            disconnected_peer)));
5708       }
5709
5710       remove_finger->trail_list[0].is_present = GNUNET_NO;
5711       //GNUNET_assert (0 != remove_friend->trails_count);
5712       //remove_friend->trails_count--; //FIXME; CHECK WHY IT FAILS AND THEN UNCOMMENT.
5713       remove_finger->is_present = GNUNET_NO;
5714       memset ((void *)&finger_table[i], 0, sizeof (finger_table[i]));
5715       continue;
5716     }
5717
5718     /* If finger is a friend but not disconnected_friend, then continue. */
5719     if (NULL != GNUNET_CONTAINER_multipeermap_get (friend_peermap,
5720                                                    &remove_finger->finger_identity))
5721       continue;
5722
5723     /* Iterate over the list of trails to reach remove_finger. Check if
5724      * disconnected_friend is the first friend in any of the trail. */
5725     removed_trails_count = remove_matching_trails (disconnected_peer,
5726                                                    remove_finger);
5727     remove_finger->trails_count =
5728             remove_finger->trails_count - removed_trails_count;
5729     /* All the finger trails had disconnected_friend as the first friend,
5730      * so free the finger. */
5731     if (remove_finger->trails_count == 0)
5732     {
5733       remove_finger->is_present = GNUNET_NO;
5734       memset ((void *)&finger_table[i], 0, sizeof (finger_table[i]));
5735     }
5736   }
5737 }
5738
5739
5740 /**
5741  * Method called whenever a peer disconnects.
5742  *
5743  * @param cls closure
5744  * @param peer peer identity this notification is about
5745  */
5746 static void
5747 handle_core_disconnect (void *cls,
5748                                           const struct GNUNET_PeerIdentity *peer)
5749 {
5750   struct FriendInfo *remove_friend;
5751
5752   /* If disconnected to own identity, then return. */
5753   if (0 == memcmp (&my_identity, peer, sizeof (struct GNUNET_PeerIdentity)))
5754     return;
5755
5756   GNUNET_assert (NULL != (remove_friend =
5757                           GNUNET_CONTAINER_multipeermap_get (friend_peermap, peer)));
5758
5759   /* Remove fingers with peer as first friend or if peer is a finger. */
5760   remove_matching_fingers (peer);
5761
5762   /* Remove any trail from routing table of which peer is a part of. This function
5763    * internally sends a trail teardown message in the direction of which
5764    * disconnected peer is not part of. */
5765   GNUNET_assert (GNUNET_SYSERR != GDS_ROUTING_remove_trail_by_peer (peer));
5766
5767   //GNUNET_assert (0 == remove_friend->trails_count); //FIXME; why should this fai.
5768
5769   /* Remove peer from friend_peermap. */
5770   GNUNET_assert (GNUNET_YES ==
5771                  GNUNET_CONTAINER_multipeermap_remove (friend_peermap,
5772                                                        peer,
5773                                                        remove_friend));
5774
5775   if (0 != GNUNET_CONTAINER_multipeermap_size (friend_peermap))
5776     return;
5777
5778   if (GNUNET_SCHEDULER_NO_TASK != find_finger_trail_task)
5779   {
5780       GNUNET_SCHEDULER_cancel (find_finger_trail_task);
5781       find_finger_trail_task = GNUNET_SCHEDULER_NO_TASK;
5782   }
5783   else
5784     GNUNET_break (0);
5785
5786 }
5787
5788
5789 /**
5790  * Method called whenever a peer connects.
5791  *
5792  * @param cls closure
5793  * @param peer_identity peer identity this notification is about
5794  */
5795 static void
5796 handle_core_connect (void *cls, const struct GNUNET_PeerIdentity *peer_identity)
5797 {
5798   struct FriendInfo *friend;
5799
5800   /* Check for connect to self message */
5801   if (0 == memcmp (&my_identity, peer_identity, sizeof (struct GNUNET_PeerIdentity)))
5802     return;
5803
5804   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected to %s\n", GNUNET_i2s (peer_identity));
5805
5806   /* If peer already exists in our friend_peermap, then exit. */
5807   if (GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains (friend_peermap,
5808                                                             peer_identity))
5809   {
5810     GNUNET_break (0);
5811     return;
5812   }
5813
5814   friend = GNUNET_new (struct FriendInfo);
5815   friend->id = *peer_identity;
5816
5817   GNUNET_assert (GNUNET_OK ==
5818                  GNUNET_CONTAINER_multipeermap_put (friend_peermap,
5819                                                     peer_identity, friend,
5820                                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
5821
5822
5823   /* got a first connection, good time to start with FIND FINGER TRAIL requests...*/
5824   if (GNUNET_SCHEDULER_NO_TASK == find_finger_trail_task)
5825   {
5826     next_send_time.rel_value_us =
5827       DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us +
5828       GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
5829                                 DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us);
5830     find_finger_trail_task = GNUNET_SCHEDULER_add_now (&send_find_finger_trail_message, NULL);
5831   }
5832 }
5833
5834
5835 /**
5836  * To be called on core init/fail.
5837  *
5838  * @param cls service closure
5839  * @param identity the public identity of this peer
5840  */
5841 static void
5842 core_init (void *cls,
5843            const struct GNUNET_PeerIdentity *identity)
5844 {
5845   my_identity = *identity;
5846
5847   uint64_t my_id64;
5848   memcpy (&my_id64, &my_identity, sizeof (uint64_t));
5849   my_id64 = GNUNET_ntohll (my_id64);
5850   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5851               "my_indentity = %s, my_id64=%llu\n",GNUNET_i2s(&my_identity),(unsigned long long)my_id64);
5852
5853 }
5854
5855
5856 /**
5857  * Initialize finger table entries.
5858  */
5859 static void
5860 finger_table_init ()
5861 {
5862   memset (&finger_table, 0, sizeof (finger_table));
5863 }
5864
5865
5866 /**
5867  * Initialize neighbours subsystem.
5868  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
5869  */
5870 int
5871 GDS_NEIGHBOURS_init (void)
5872 {
5873   static struct GNUNET_CORE_MessageHandler core_handlers[] = {
5874     {&handle_dht_p2p_put, GNUNET_MESSAGE_TYPE_XDHT_P2P_PUT, 0},
5875     {&handle_dht_p2p_get, GNUNET_MESSAGE_TYPE_XDHT_P2P_GET, 0},
5876     {&handle_dht_p2p_get_result, GNUNET_MESSAGE_TYPE_XDHT_P2P_GET_RESULT, 0},
5877     {&handle_dht_p2p_trail_setup, GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_SETUP, 0},
5878     {&handle_dht_p2p_trail_setup_result, GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_SETUP_RESULT, 0},
5879     {&handle_dht_p2p_verify_successor, GNUNET_MESSAGE_TYPE_XDHT_P2P_VERIFY_SUCCESSOR, 0},
5880     {&handle_dht_p2p_verify_successor_result, GNUNET_MESSAGE_TYPE_XDHT_P2P_VERIFY_SUCCESSOR_RESULT, 0},
5881     {&handle_dht_p2p_notify_new_successor, GNUNET_MESSAGE_TYPE_XDHT_P2P_NOTIFY_NEW_SUCCESSOR, 0},
5882     {&handle_dht_p2p_trail_setup_rejection, GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_SETUP_REJECTION, 0},
5883     {&handle_dht_p2p_trail_compression, GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_COMPRESSION,
5884                                         sizeof (struct PeerTrailCompressionMessage)},
5885     {&handle_dht_p2p_trail_teardown, GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_TEARDOWN,
5886                                      sizeof (struct PeerTrailTearDownMessage)},
5887     {&handle_dht_p2p_add_trail, GNUNET_MESSAGE_TYPE_XDHT_P2P_ADD_TRAIL, 0},
5888     {NULL, 0, 0}
5889   };
5890
5891   core_api =
5892     GNUNET_CORE_connect (GDS_cfg, NULL, &core_init, &handle_core_connect,
5893                          &handle_core_disconnect, NULL, GNUNET_NO, NULL,
5894                          GNUNET_NO, core_handlers);
5895   if (NULL == core_api)
5896     return GNUNET_SYSERR;
5897
5898   friend_peermap = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_NO);
5899   finger_table_init ();
5900
5901   return GNUNET_OK;
5902 }
5903
5904
5905 /**
5906  * Shutdown neighbours subsystem.
5907  */
5908 void
5909 GDS_NEIGHBOURS_done (void)
5910 {
5911   if (NULL == core_api)
5912     return;
5913
5914   GNUNET_CORE_disconnect (core_api);
5915   core_api = NULL;
5916
5917   GNUNET_assert (0 == GNUNET_CONTAINER_multipeermap_size (friend_peermap));
5918   GNUNET_CONTAINER_multipeermap_destroy (friend_peermap);
5919   friend_peermap = NULL;
5920
5921   if (GNUNET_SCHEDULER_NO_TASK != find_finger_trail_task)
5922   {
5923     GNUNET_break (0);
5924     GNUNET_SCHEDULER_cancel (find_finger_trail_task);
5925     find_finger_trail_task = GNUNET_SCHEDULER_NO_TASK;
5926   }
5927
5928   if (GNUNET_SCHEDULER_NO_TASK != send_verify_successor_task)
5929   {
5930     GNUNET_SCHEDULER_cancel (send_verify_successor_task);
5931     send_verify_successor_task = GNUNET_SCHEDULER_NO_TASK;
5932   }
5933 }
5934
5935
5936 /**
5937  * Get my identity
5938  *
5939  * @return my identity
5940  */
5941 struct GNUNET_PeerIdentity
5942 GDS_NEIGHBOURS_get_my_id (void)
5943 {
5944   return my_identity;
5945 }
5946
5947 /* end of gnunet-service-xdht_neighbours.c */