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