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