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