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