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