xvine:fixes
[oweals/gnunet.git] / src / dht / gnunet-service-xdht_neighbours.c
1 /*
2      This file is part of GNUnet.
3      (C) 2009-2014 Christian Grothoff (and other contributing authors)
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21 /**
22  * @file dht/gnunet-service-xdht_neighbours.c
23  * @brief GNUnet DHT service's finger and friend table management code
24  * @author Supriti Singh
25  */
26
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
29 #include "gnunet_block_lib.h"
30 #include "gnunet_hello_lib.h"
31 #include "gnunet_constants.h"
32 #include "gnunet_protocols.h"
33 #include "gnunet_ats_service.h"
34 #include "gnunet_core_service.h"
35 #include "gnunet_datacache_lib.h"
36 #include "gnunet_transport_service.h"
37 #include "gnunet_dht_service.h"
38 #include "gnunet_statistics_service.h"
39 #include "gnunet-service-xdht.h"
40 #include "gnunet-service-xdht_clients.h"
41 #include "gnunet-service-xdht_datacache.h"
42 #include "gnunet-service-xdht_neighbours.h"
43 #include "gnunet-service-xdht_routing.h"
44 #include <fenv.h>
45 #include "dht.h"
46
47 /**
48  * 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_MILLISECONDS, 50)
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.rel_value_us =
2528       find_finger_trail_task_next_send_time.rel_value_us +
2529       GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
2530                                 DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us);
2531   find_finger_trail_task =
2532       GNUNET_SCHEDULER_add_delayed (find_finger_trail_task_next_send_time,
2533                                     &send_find_finger_trail_message,
2534                                     NULL);
2535
2536    /* No space in my routing table. (Source and destination peers also store entries
2537    * in their routing table).  */
2538   if (GNUNET_YES == GDS_ROUTING_threshold_reached())
2539     return;
2540
2541   target_friend = select_random_friend ();
2542   if (NULL == target_friend)
2543   {
2544     return;
2545   }
2546
2547   finger_id_value = compute_finger_identity_value (current_search_finger_index);
2548
2549   if (PREDECESSOR_FINGER_ID == current_search_finger_index)
2550     is_predecessor = 1;
2551   else
2552     is_predecessor = 0;
2553
2554   /* Generate a unique trail id for trail we are trying to setup. */
2555   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG,
2556                               &trail_id, sizeof (trail_id));
2557   memset(&intermediate_trail_id, 0, sizeof (struct GNUNET_HashCode));
2558   GDS_NEIGHBOURS_send_trail_setup (my_identity, finger_id_value,
2559                                    target_friend->id, target_friend, 0, NULL,
2560                                    is_predecessor, trail_id,
2561                                    intermediate_trail_id);
2562 }
2563
2564
2565 /**
2566  * In case there are already maximum number of possible trails to reach to a
2567  * finger, then check if the new trail's length is lesser than any of the
2568  * existing trails.
2569  * If yes then replace that old trail by new trail.
2570  *
2571  * Note: Here we are taking length as a parameter to choose the best possible
2572  * trail, but there could be other parameters also like:
2573  * 1. duration of existence of a trail - older the better.
2574  * 2. if the new trail is completely disjoint than the
2575  *    other trails, then may be choosing it is better.
2576  *
2577  * @param finger Finger 
2578  * @param new_finger_trail List of peers to reach from me to @a finger, NOT
2579  *                         including the endpoints. 
2580  * @param new_finger_trail_length Total number of peers in @a new_finger_trail
2581  * @param new_finger_trail_id Unique identifier of @a new_finger_trail.
2582  */
2583 static void
2584 select_and_replace_trail (struct FingerInfo *finger,
2585                           const struct GNUNET_PeerIdentity *new_trail,
2586                           unsigned int new_trail_length,
2587                           struct GNUNET_HashCode new_trail_id)
2588 {
2589   struct Trail *trail;
2590   unsigned int largest_trail_length;
2591   unsigned int largest_trail_index;
2592   struct Trail_Element *trail_element;
2593   unsigned int i;
2594
2595   largest_trail_length = new_trail_length;
2596   largest_trail_index = MAXIMUM_TRAILS_PER_FINGER + 1;
2597
2598   GNUNET_assert (MAXIMUM_TRAILS_PER_FINGER == finger->trails_count);
2599
2600   for (i = 0; i < finger->trails_count; i++)
2601   {
2602     trail = &finger->trail_list[i];
2603     if (trail->trail_length > largest_trail_length)
2604     {
2605       largest_trail_length = trail->trail_length;
2606       largest_trail_index = i;
2607     }
2608   }
2609
2610   /* New trail is not better than existing ones. Send trail teardown. */
2611   if (largest_trail_index == (MAXIMUM_TRAILS_PER_FINGER + 1))
2612   {
2613     struct GNUNET_PeerIdentity next_hop;
2614
2615     memcpy (&next_hop, &new_trail[0], sizeof(struct GNUNET_PeerIdentity));
2616     GDS_ROUTING_remove_trail (new_trail_id);
2617     GDS_NEIGHBOURS_send_trail_teardown (new_trail_id,
2618                                         GDS_ROUTING_SRC_TO_DEST,
2619                                         next_hop);
2620     return;
2621   }
2622
2623   /* Send trail teardown message across the replaced trail. */
2624   struct Trail *replace_trail = &finger->trail_list[largest_trail_index];
2625   
2626   GNUNET_assert (GNUNET_YES == GDS_ROUTING_remove_trail (replace_trail->trail_id));
2627   GDS_NEIGHBOURS_send_trail_teardown (replace_trail->trail_id,
2628                                       GDS_ROUTING_SRC_TO_DEST,
2629                                       replace_trail->trail_head->peer);
2630   /* Free the trail. */
2631   while (NULL != (trail_element = replace_trail->trail_head))
2632   {
2633     GNUNET_CONTAINER_DLL_remove (replace_trail->trail_head,
2634                                  replace_trail->trail_tail, trail_element);
2635     GNUNET_free_non_null (trail_element);
2636   }
2637
2638   /* Add new trial at that location. */
2639   replace_trail->is_present = GNUNET_YES;
2640   replace_trail->trail_length = new_trail_length;
2641   replace_trail->trail_id = new_trail_id;
2642   
2643   for (i = 0; i < new_trail_length; i++)
2644   {
2645     struct Trail_Element *element = GNUNET_new (struct Trail_Element);
2646     element->peer = new_trail[i];
2647
2648     GNUNET_CONTAINER_DLL_insert_tail (replace_trail->trail_head,
2649                                       replace_trail->trail_tail,
2650                                       element);
2651   }
2652   /* FIXME: URGENT Are we adding the trail back to the list. */
2653 }
2654
2655
2656 /**
2657  * Check if the new trail to reach to finger is unique or do we already have
2658  * such a trail present for finger.
2659  * @param existing_finger Finger identity
2660  * @param new_trail New trail to reach @a existing_finger
2661  * @param trail_length Total number of peers in new_trail.
2662  * @return #GNUNET_YES if the new trail is unique
2663  *         #GNUNET_NO if same trail is already present.
2664  */
2665 static int
2666 is_new_trail_unique (struct FingerInfo *existing_finger,
2667                      const struct GNUNET_PeerIdentity *new_trail,
2668                      unsigned int trail_length)
2669 {
2670   struct Trail *trail;
2671   struct Trail_Element *trail_element;
2672   int i;
2673   int j;
2674   
2675   GNUNET_assert (existing_finger->trails_count > 0);
2676
2677   /* Iterate over list of trails. */
2678   for (i = 0; i < existing_finger->trails_count; i++)
2679   {
2680     trail = &(existing_finger->trail_list[i]);
2681     GNUNET_assert (GNUNET_YES == trail->is_present);
2682
2683     /* New trail and existing trail length are not same. */
2684     if (trail->trail_length != trail_length)
2685     {
2686       return GNUNET_YES;
2687     }
2688
2689     trail_element = trail->trail_head;
2690     GNUNET_assert (trail_element != NULL);
2691     for (j = 0; j < trail->trail_length; j++)
2692     {
2693       if (0 != GNUNET_CRYPTO_cmp_peer_identity (&new_trail[j],
2694                                                 &trail_element->peer))
2695       {
2696         return GNUNET_YES;
2697       }
2698       trail_element = trail_element->next;
2699     }
2700   }
2701   return GNUNET_NO;
2702 }
2703
2704
2705 /** 
2706  * FIXME; In case of multiple trails, we may have a case where a trail from in
2707  * between has been removed, then we should try to find a free slot , not simply
2708  * add a trail at then end of the list. 
2709  * Add a new trail to existing finger. This function is called only when finger
2710  * is not my own identity or a friend.
2711  * @param existing_finger Finger
2712  * @param new_finger_trail New trail from me to finger, NOT including endpoints
2713  * @param new_finger_trail_length Total number of peers in @a new_finger_trail
2714  * @param new_finger_trail_id Unique identifier of the trail.
2715  */
2716 static void
2717 add_new_trail (struct FingerInfo *existing_finger,
2718                const struct GNUNET_PeerIdentity *new_trail,
2719                unsigned int new_trail_length,
2720                struct GNUNET_HashCode new_trail_id)
2721 {
2722   struct Trail *trail;
2723   struct FriendInfo *first_friend;
2724   int i;
2725   int index;
2726   
2727   if (GNUNET_NO == is_new_trail_unique (existing_finger, new_trail,
2728                                         new_trail_length))
2729   {
2730     return;
2731   }
2732   
2733   index = existing_finger->trails_count;
2734   trail = &existing_finger->trail_list[index];
2735   GNUNET_assert (GNUNET_NO == trail->is_present);
2736   trail->trail_id = new_trail_id;
2737   trail->trail_length = new_trail_length;
2738   existing_finger->trails_count++;
2739   trail->is_present = GNUNET_YES;
2740
2741   GNUNET_assert (NULL == (GNUNET_CONTAINER_multipeermap_get (friend_peermap,
2742                                                              &existing_finger->finger_identity)));
2743   /* If finger is a friend then we never call this function. */
2744   GNUNET_assert (new_trail_length > 0);
2745
2746   first_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap,
2747                                                     &new_trail[0]);
2748   first_friend->trails_count++;
2749
2750   for (i = 0; i < new_trail_length; i++)
2751   {
2752     struct Trail_Element *element;
2753
2754     element = GNUNET_new (struct Trail_Element);
2755     element->peer = new_trail[i];
2756     GNUNET_CONTAINER_DLL_insert_tail (trail->trail_head,
2757                                       trail->trail_tail,
2758                                       element);
2759   }
2760   /* Do we need to add trail head and trail tail in the trail list itearator.*/
2761   existing_finger->trail_list[index].trail_head = trail->trail_head;
2762   existing_finger->trail_list[index].trail_tail = trail->trail_tail;
2763   existing_finger->trail_list[index].trail_length = new_trail_length;
2764   existing_finger->trail_list[index].trail_id = new_trail_id;
2765   existing_finger->trail_list[index].is_present = GNUNET_YES;
2766 }
2767
2768
2769 /**
2770  * FIXME Check if this function is called for opposite direction if yes then
2771  * take it as parameter.
2772  * Get the next hop to send trail teardown message from routing table and
2773  * then delete the entry from routing table. Send trail teardown message for a
2774  * specific trail of a finger.
2775  * @param finger Finger whose trail is to be removed.
2776  * @param trail List of peers in trail from me to a finger, NOT including
2777  *              endpoints.
2778  */
2779 static void
2780 send_trail_teardown (struct FingerInfo *finger,
2781                      struct Trail *trail)
2782 {
2783   struct FriendInfo *friend;
2784   struct GNUNET_PeerIdentity *next_hop;
2785
2786   next_hop = GDS_ROUTING_get_next_hop (trail->trail_id,
2787                                        GDS_ROUTING_SRC_TO_DEST);
2788   
2789   if (NULL == next_hop)
2790   {
2791     DEBUG(" NO ENTRY FOUND IN %s ROUTING TABLE for trail id %s, line",
2792             GNUNET_i2s(&my_identity), GNUNET_h2s(&trail->trail_id), __LINE__);
2793     GNUNET_break(0);
2794     return;
2795   }
2796   
2797   GNUNET_assert (0 != GNUNET_CRYPTO_cmp_peer_identity (&finger->finger_identity,
2798                                                        &my_identity));
2799
2800   /*FIXME: here was an assertion that trail->is_present = GNUNET_YES. But it 
2801    used to fail. We have removed assertion with a condition, just for now.
2802    Find out the reason why assertion failed. */
2803   if (trail->is_present == GNUNET_NO)
2804   {
2805     DEBUG(" trail id %s of peer %s is not present to send a trail teardown message., line",
2806             GNUNET_i2s(&my_identity), GNUNET_h2s(&trail->trail_id), __LINE__);
2807     return;
2808   }
2809
2810   /* Finger is not a friend. */
2811   if (trail->trail_length > 0)
2812   {
2813     friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap,
2814                                                 &trail->trail_head->peer);
2815   }
2816   else
2817   {
2818     friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap,
2819                                                 &finger->finger_identity);
2820   }
2821
2822   if(NULL == friend)
2823   {
2824     DEBUG ("\n LINE NO: = %d, Friend not found for trail id  %s of peer %s trail length = %d",
2825            __LINE__,GNUNET_h2s(&trail->trail_id), GNUNET_i2s(&my_identity),trail->trail_length);
2826     return;
2827   }
2828   if (0 != GNUNET_CRYPTO_cmp_peer_identity (next_hop, &friend->id)
2829       && (0 == trail->trail_length))
2830   {
2831      DEBUG ("\n LINE NO: = %d, Friend not found for trail id  %s of peer %s trail length = %d",
2832            __LINE__,GNUNET_h2s(&trail->trail_id), GNUNET_i2s(&my_identity),trail->trail_length);
2833     return;
2834   }
2835   GNUNET_assert (GNUNET_YES == GDS_ROUTING_remove_trail (trail->trail_id));
2836   friend->trails_count--;
2837   GDS_NEIGHBOURS_send_trail_teardown (trail->trail_id,
2838                                       GDS_ROUTING_SRC_TO_DEST,
2839                                       friend->id);
2840 }
2841
2842
2843 /**
2844  * Send trail teardown message across all the trails to reach to finger.
2845  * @param finger Finger whose all the trail should be freed.
2846  */
2847 static void
2848 send_all_finger_trails_teardown (struct FingerInfo *finger)
2849 {
2850   unsigned int i;
2851   for (i = 0; i < finger->trails_count; i++)
2852   {
2853     struct Trail *trail;
2854
2855     trail = &finger->trail_list[i];
2856     GNUNET_assert (trail->is_present == GNUNET_YES);
2857     send_trail_teardown (finger, trail);
2858     trail->is_present = GNUNET_NO;
2859    }
2860 }
2861
2862
2863 /**
2864  * Free a specific trail
2865  * @param trail List of peers to be freed.
2866  */
2867 static void
2868 free_trail (struct Trail *trail)
2869 {
2870   struct Trail_Element *trail_element;
2871
2872   while (NULL != (trail_element = trail->trail_head))
2873   {
2874     GNUNET_CONTAINER_DLL_remove (trail->trail_head,
2875                                  trail->trail_tail,
2876                                  trail_element);
2877     GNUNET_free_non_null (trail_element);
2878   }
2879   trail->trail_head = NULL;
2880   trail->trail_tail = NULL;
2881 }
2882
2883
2884 /**
2885  * Free finger and its trail.
2886  * @param finger Finger to be freed.
2887  * @param finger_table_index Index at which finger is stored.
2888  */
2889 static void
2890 free_finger (struct FingerInfo *finger, unsigned int finger_table_index)
2891 {
2892   struct Trail *trail;
2893   unsigned int i;
2894   for (i = 0; i < finger->trails_count; i++)
2895   {
2896     trail = &finger->trail_list[i];
2897     if (GNUNET_NO == trail->is_present)
2898       continue;
2899
2900     if (trail->trail_length > 0)
2901       free_trail (trail);
2902     trail->is_present = GNUNET_NO;
2903   }
2904
2905   finger->is_present = GNUNET_NO;
2906   memset ((void *)&finger_table[finger_table_index], 0, sizeof (finger_table[finger_table_index]));
2907 }
2908
2909
2910 /**
2911  * Add a new entry in finger table at finger_table_index.
2912  * In case I am my own finger, then we don't have a trail. In case of a friend,
2913  * we have a trail with unique id and '0' trail length.
2914  * In case a finger is a friend, then increment the trails count of the friend.
2915  * @param finger_identity Peer Identity of new finger
2916  * @param finger_trail Trail to reach from me to finger (excluding both end points).
2917  * @param finger_trail_length Total number of peers in @a finger_trail.
2918  * @param trail_id Unique identifier of the trail.
2919  * @param finger_table_index Index in finger table.
2920  */
2921 static void
2922 add_new_finger (struct GNUNET_PeerIdentity finger_identity,
2923                 const struct GNUNET_PeerIdentity *finger_trail,
2924                 unsigned int finger_trail_length,
2925                 struct GNUNET_HashCode trail_id,
2926                 unsigned int finger_table_index)
2927 {
2928   struct FingerInfo *new_entry;
2929   struct FriendInfo *first_trail_hop;
2930   struct Trail *trail;
2931   int i;
2932   
2933   new_entry = GNUNET_new (struct FingerInfo);
2934   new_entry->finger_identity = finger_identity;
2935   new_entry->finger_table_index = finger_table_index;
2936   new_entry->is_present = GNUNET_YES;
2937   
2938   /* If the new entry is my own identity. */
2939   if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity,
2940                                             &finger_identity))
2941   {
2942     new_entry->trails_count = 0;
2943     finger_table[finger_table_index] = *new_entry;
2944     GNUNET_free (new_entry);
2945     return;
2946   }
2947   
2948   /* If finger is a friend, then we don't actually have a trail.
2949    *  Just a trail id */
2950   if (NULL != GNUNET_CONTAINER_multipeermap_get (friend_peermap,
2951                                                  &finger_identity))
2952   {
2953     new_entry->trail_list[0].trail_id = trail_id;
2954     new_entry->trails_count = 1;
2955     new_entry->trail_list[0].is_present = GNUNET_YES;
2956     new_entry->trail_list[0].trail_length = 0;
2957     new_entry->trail_list[0].trail_head = NULL;
2958     new_entry->trail_list[0].trail_tail = NULL;
2959     finger_table[finger_table_index] = *new_entry;
2960     GNUNET_assert (NULL !=
2961                   (first_trail_hop =
2962                        GNUNET_CONTAINER_multipeermap_get (friend_peermap,
2963                                                           &finger_identity)));
2964
2965     first_trail_hop->trails_count++;
2966     GNUNET_free (new_entry);
2967     return;
2968   }
2969
2970   GNUNET_assert (NULL !=
2971                 (first_trail_hop =
2972                        GNUNET_CONTAINER_multipeermap_get (friend_peermap,
2973                                                           &finger_trail[0])));
2974   new_entry->trails_count = 1;
2975   first_trail_hop->trails_count++;
2976   GNUNET_assert (finger_trail_length != 0);
2977   /* Copy the finger trail into trail. */
2978   trail = GNUNET_new (struct Trail);
2979   for(i = 0; i < finger_trail_length; i++)
2980   {
2981     struct Trail_Element *element = GNUNET_new (struct Trail_Element);
2982
2983     element->next = NULL;
2984     element->prev = NULL;
2985     element->peer = finger_trail[i];
2986     GNUNET_CONTAINER_DLL_insert_tail (trail->trail_head,
2987                                       trail->trail_tail,
2988                                       element);
2989   }
2990  
2991
2992   /* Add trail to trail list. */
2993   new_entry->trail_list[0].trail_head = trail->trail_head;
2994   new_entry->trail_list[0].trail_tail = trail->trail_tail;
2995   new_entry->trail_list[0].trail_length = finger_trail_length;
2996   new_entry->trail_list[0].trail_id = trail_id;
2997   new_entry->trail_list[0].is_present = GNUNET_YES;
2998   finger_table[finger_table_index] = *new_entry;
2999   GNUNET_free (new_entry);
3000   return;
3001 }
3002
3003
3004 /**
3005  * Periodic task to verify current successor. There can be multiple trails to reach
3006  * to successor, choose the shortest one and send verify successor message
3007  * across that trail.
3008  * @param cls closure for this task
3009  * @param tc the context under which the task is running
3010  */
3011 static void
3012 send_verify_successor_message (void *cls,
3013                                 const struct GNUNET_SCHEDULER_TaskContext *tc)
3014 {
3015   struct FriendInfo *target_friend;
3016   struct GNUNET_HashCode trail_id;
3017   int i;
3018   struct Trail *trail;
3019   struct Trail_Element *element;
3020   unsigned int trail_length;
3021   unsigned int j = 0;
3022   struct FingerInfo *successor;
3023
3024   /* Schedule another send_find_finger_trail_message task. 
3025   verify_successor_next_send_time.rel_value_us =
3026       verify_successor_next_send_time.rel_value_us +
3027       GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
3028                                 DHT_SEND_VERIFY_SUCCESSOR_INTERVAL.rel_value_us);*/
3029   send_verify_successor_task =
3030       GNUNET_SCHEDULER_add_delayed (verify_successor_next_send_time,
3031                                     &send_verify_successor_message,
3032                                     NULL);
3033
3034   successor = &finger_table[0];
3035   for (i = 0; i < successor->trails_count; i++)
3036   {
3037     trail = &successor->trail_list[i];
3038     if(GNUNET_YES == trail->is_present)
3039       break;
3040   }
3041   
3042   /* No valid trail found to reach to successor. */
3043   if (i == successor->trails_count)
3044     return;
3045   
3046   GNUNET_assert(0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity,
3047                                                       &successor->finger_identity));
3048
3049   /* Trail stored at this index. */
3050   GNUNET_assert (GNUNET_YES == trail->is_present);
3051   
3052   trail_id = trail->trail_id;
3053   if (NULL == GDS_ROUTING_get_next_hop(trail_id,GDS_ROUTING_SRC_TO_DEST))
3054   {
3055     DEBUG(" NO ENTRY FOUND IN %s ROUTING TABLE for trail id %s, line",
3056             GNUNET_i2s(&my_identity), GNUNET_h2s(&trail->trail_id), __LINE__);
3057     GNUNET_break(0);
3058     return;
3059   }
3060   trail_length = trail->trail_length;
3061   
3062   if (trail_length > 0)
3063   {
3064      /* Copy the trail into peer list. */
3065     struct GNUNET_PeerIdentity peer_list[trail_length];
3066
3067     element = trail->trail_head;
3068     for(j = 0; j < trail_length; j++)
3069     {
3070       peer_list[j] = element->peer;
3071       element = element->next;
3072     }
3073
3074     GNUNET_assert (NULL != (target_friend =
3075                             GNUNET_CONTAINER_multipeermap_get (friend_peermap,
3076                                                                &peer_list[0])));
3077     GDS_NEIGHBOURS_send_verify_successor_message (my_identity,
3078                                                   successor->finger_identity,
3079                                                   trail_id, peer_list, trail_length,
3080                                                   target_friend);
3081     return;
3082   }
3083   else
3084   {
3085     GNUNET_assert (NULL != (target_friend =
3086                             GNUNET_CONTAINER_multipeermap_get (friend_peermap,
3087                                                                &successor->finger_identity)));
3088     GDS_NEIGHBOURS_send_verify_successor_message (my_identity,
3089                                                   successor->finger_identity,
3090                                                   trail_id, NULL, 0,
3091                                                   target_friend);
3092     return;
3093   }
3094 }
3095
3096
3097 /**
3098  * FIXME: should this be a periodic task, incrementing the search finger index?
3099  * Update the current search finger index.
3100  *
3101  * FIXME document parameters!
3102  */
3103 static void
3104 update_current_search_finger_index (struct GNUNET_PeerIdentity finger_identity,
3105                                     unsigned int finger_table_index)
3106 {
3107   struct FingerInfo *successor;
3108
3109   /* FIXME correct this: only move current index periodically */
3110   if (finger_table_index != current_search_finger_index)
3111     return;
3112
3113   successor = &finger_table[0];
3114   GNUNET_assert (GNUNET_YES == successor->is_present);
3115
3116   /* We were looking for immediate successor.  */
3117   if (0 == current_search_finger_index)
3118   {
3119     /* Start looking for immediate predecessor. */
3120     current_search_finger_index = PREDECESSOR_FINGER_ID;
3121
3122     if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &finger_identity))
3123     {
3124       if (GNUNET_SCHEDULER_NO_TASK == send_verify_successor_task)
3125       {
3126         send_verify_successor_task = 
3127                 GNUNET_SCHEDULER_add_now (&send_verify_successor_message, NULL);
3128       }
3129     }
3130     return;
3131   }
3132
3133   current_search_finger_index = current_search_finger_index - 1;
3134   return;
3135 }
3136
3137
3138 /**
3139  * Get the least significant bit set in val.
3140  *
3141  * @param val Value
3142  * @return Position of first bit set, 65 in case of error.
3143  */
3144 static unsigned int
3145 find_set_bit (uint64_t val)
3146 {
3147   uint64_t i;
3148   unsigned int pos;
3149
3150   i = 1;
3151   pos = 0;
3152
3153   while (!(i & val))
3154   {
3155     i = i << 1;
3156     pos++;
3157     if (pos > 63)
3158     {
3159       GNUNET_break (0);
3160       return 65;
3161     }
3162   }
3163
3164   if (val/i != 1)
3165     return 65; /* Some other bit was set to 1 as well. */
3166
3167   return pos;
3168 }
3169
3170
3171 /**
3172  * Calculate finger_table_index from initial 64 bit finger identity value that
3173  * we send in trail setup message.
3174  * @param ultimate_destination_finger_value Value that we calculated from our
3175  *                                          identity and finger_table_index.
3176  * @param is_predecessor Is the entry for predecessor or not?
3177  * @return finger_table_index Value between 0 <= finger_table_index <= 64
3178  *         finger_table_index > PREDECESSOR_FINGER_ID, if error occurs.
3179  */
3180 static unsigned int
3181 get_finger_table_index (uint64_t ultimate_destination_finger_value,
3182                         unsigned int is_predecessor)
3183 {
3184   uint64_t my_id64;
3185   uint64_t diff;
3186   unsigned int finger_table_index;
3187
3188   memcpy (&my_id64, &my_identity, sizeof (uint64_t));
3189   my_id64 = GNUNET_ntohll (my_id64);
3190
3191   /* Is this a predecessor finger? */
3192   if (1 == is_predecessor)
3193   {
3194     diff =  my_id64 - ultimate_destination_finger_value;
3195     if (1 == diff)
3196       finger_table_index = PREDECESSOR_FINGER_ID;
3197     else
3198       finger_table_index = PREDECESSOR_FINGER_ID + 1; //error value
3199
3200   }
3201   else
3202   {
3203     diff = ultimate_destination_finger_value - my_id64;
3204     finger_table_index = find_set_bit (diff);
3205   }
3206   return finger_table_index;
3207 }
3208
3209
3210 /**
3211  * Remove finger and its associated data structures from finger table.
3212  * @param existing_finger Finger to be removed which is in finger table. 
3213  * @param finger_table_index Index in finger table where @a existing_finger
3214  *                           is stored.
3215  */
3216 static void
3217 remove_existing_finger (struct FingerInfo *existing_finger,
3218                         unsigned int finger_table_index)
3219 {
3220   GNUNET_assert (GNUNET_YES == existing_finger->is_present);
3221
3222   /* If I am my own finger, then we have no trails. */
3223   if (0 == GNUNET_CRYPTO_cmp_peer_identity (&existing_finger->finger_identity,
3224                                             &my_identity))
3225   {
3226     existing_finger->is_present = GNUNET_NO;
3227     memset ((void *)&finger_table[finger_table_index], 0,
3228             sizeof (finger_table[finger_table_index]));
3229     return;
3230   }
3231
3232   /* For all other fingers, send trail teardown across all the trails to reach
3233    finger, and free the finger. */
3234   send_all_finger_trails_teardown (existing_finger);
3235   free_finger (existing_finger, finger_table_index);
3236   return;
3237 }
3238
3239
3240 /**
3241  * Check if there is already an entry in finger_table at finger_table_index.
3242  * We get the finger_table_index from 64bit finger value we got from the network.
3243  * -- If yes, then select the closest finger.
3244  *   -- If new and existing finger are same, then check if you can store more
3245  *      trails.
3246  *      -- If yes then add trail, else keep the best trails to reach to the
3247  *         finger.
3248  *   -- If the new finger is closest, remove the existing entry, send trail
3249  *      teardown message across all the trails to reach the existing entry.
3250  *      Add the new finger.
3251  *  -- If new and existing finger are different, and existing finger is closest
3252  *     then do nothing.
3253  * -- Update current_search_finger_index.
3254  * @param finger_identity Peer Identity of new finger
3255  * @param finger_trail Trail to reach the new finger
3256  * @param finger_trail_length Total number of peers in @a new_finger_trail.
3257  * @param is_predecessor Is this entry for predecessor in finger_table?
3258  * @param finger_value 64 bit value of finger identity that we got from network.
3259  * @param finger_trail_id Unique identifier of @finger_trail.
3260  */
3261 static void
3262 finger_table_add (struct GNUNET_PeerIdentity finger_identity,
3263                   const struct GNUNET_PeerIdentity *finger_trail,
3264                   unsigned int finger_trail_length,
3265                   unsigned int is_predecessor,
3266                   uint64_t finger_value,
3267                   struct GNUNET_HashCode finger_trail_id)
3268 {
3269   struct FingerInfo *existing_finger;
3270   struct GNUNET_PeerIdentity closest_peer;
3271   struct FingerInfo *successor;
3272   unsigned int finger_table_index;
3273
3274   /* Get the finger_table_index corresponding to finger_value we got from network.*/
3275   finger_table_index = get_finger_table_index (finger_value, is_predecessor);
3276
3277   /* Invalid finger_table_index. */
3278   if ((finger_table_index > PREDECESSOR_FINGER_ID))
3279   {
3280     GNUNET_break_op (0);
3281     return;
3282   }
3283
3284   /* New entry same as successor. */
3285   if ((0 != finger_table_index) &&
3286       (PREDECESSOR_FINGER_ID != finger_table_index))
3287   {
3288     successor = &finger_table[0];
3289     if (GNUNET_NO == successor->is_present)
3290     {
3291       GNUNET_break (0);
3292       return;
3293     }
3294     if (0 == GNUNET_CRYPTO_cmp_peer_identity (&finger_identity,
3295                                               &successor->finger_identity))
3296     {
3297       find_finger_trail_task_next_send_time = 
3298               GNUNET_TIME_STD_BACKOFF(find_finger_trail_task_next_send_time);
3299       current_search_finger_index = 0;
3300       return;
3301     }
3302     
3303     struct FingerInfo prev_finger;
3304     prev_finger = finger_table[finger_table_index - 1];
3305     if (0 == GNUNET_CRYPTO_cmp_peer_identity (&finger_identity,
3306                                               &prev_finger.finger_identity))
3307     {
3308        current_search_finger_index--;
3309        return;
3310     }
3311   }
3312
3313   existing_finger = &finger_table[finger_table_index];
3314
3315   /* No entry present in finger_table for given finger map index. */
3316   if (GNUNET_NO == existing_finger->is_present)
3317   {
3318     add_new_finger (finger_identity, finger_trail,
3319                     finger_trail_length,
3320                     finger_trail_id, finger_table_index);
3321     update_current_search_finger_index (finger_identity,
3322                                         finger_table_index);
3323     return;
3324   }
3325
3326
3327   /* If existing entry and finger identity are not same. */
3328   if (0 != GNUNET_CRYPTO_cmp_peer_identity (&(existing_finger->finger_identity),
3329                                             &finger_identity))
3330   {
3331     closest_peer = select_closest_peer (&existing_finger->finger_identity,
3332                                         &finger_identity,
3333                                         finger_value,
3334                                         is_predecessor);
3335
3336     /* If the new finger is the closest peer. */
3337     if (0 == GNUNET_CRYPTO_cmp_peer_identity (&finger_identity, &closest_peer))
3338     {
3339       remove_existing_finger (existing_finger, finger_table_index);
3340       add_new_finger (finger_identity, finger_trail, finger_trail_length,
3341                       finger_trail_id, finger_table_index);
3342     }
3343     else
3344     {
3345       /* Existing finger is the closest one. We need to send trail teardown
3346          across the trail setup in routing table of all the peers. */
3347       if (0 != GNUNET_CRYPTO_cmp_peer_identity (&finger_identity, &my_identity))
3348       {
3349         if (finger_trail_length > 0)
3350           GDS_NEIGHBOURS_send_trail_teardown (finger_trail_id,
3351                                               GDS_ROUTING_SRC_TO_DEST,
3352                                               finger_trail[0]);
3353         else
3354           GDS_NEIGHBOURS_send_trail_teardown (finger_trail_id,
3355                                               GDS_ROUTING_SRC_TO_DEST,
3356                                               finger_identity);
3357       }
3358     }
3359   }
3360   else
3361   {
3362     /* If both new and existing entry are same as my_identity, then do nothing. */
3363     if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(existing_finger->finger_identity),
3364                                               &my_identity))
3365     {
3366       return;
3367     }
3368     /* If the existing finger is not a friend. */
3369     if (NULL ==
3370         GNUNET_CONTAINER_multipeermap_get (friend_peermap,
3371                                            &existing_finger->finger_identity))
3372     {
3373       /* If there is space to store more trails. */
3374       if (existing_finger->trails_count < MAXIMUM_TRAILS_PER_FINGER)
3375         add_new_trail (existing_finger, finger_trail,
3376                        finger_trail_length, finger_trail_id);
3377       else
3378         select_and_replace_trail (existing_finger, finger_trail,
3379                                   finger_trail_length, finger_trail_id);
3380
3381     }
3382   }
3383   update_current_search_finger_index (finger_identity, finger_table_index);
3384   return;
3385 }
3386
3387
3388 /**
3389  * FIXME: Check for loop in the request. If you already are part of put path,
3390  * then you need to reset the put path length.
3391  * Core handler for P2P put messages.
3392  * @param cls closure
3393  * @param peer sender of the request
3394  * @param message message
3395  * @return #GNUNET_OK to keep the connection open,
3396  *         #GNUNET_SYSERR to close it (signal serious error)
3397  */
3398 static int
3399 handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer,
3400                     const struct GNUNET_MessageHeader *message)
3401 {
3402   struct PeerPutMessage *put;
3403   struct GNUNET_PeerIdentity *put_path;
3404   struct GNUNET_PeerIdentity best_known_dest;
3405   struct GNUNET_HashCode intermediate_trail_id;
3406   struct GNUNET_PeerIdentity *next_hop;
3407   enum GNUNET_DHT_RouteOption options;
3408   struct GNUNET_HashCode test_key;
3409   void *payload;
3410   size_t msize;
3411   uint32_t putlen;
3412   size_t payload_size;
3413   uint64_t key_value;
3414
3415 #if ENABLE_MALICIOUS
3416   if(1 == act_malicious)
3417   {
3418     DEBUG("I am malicious,dropping put request. \n");
3419     return GNUNET_OK;
3420   }
3421 #endif
3422   
3423   msize = ntohs (message->size);
3424   if (msize < sizeof (struct PeerPutMessage))
3425   {
3426     GNUNET_break_op (0);
3427     return GNUNET_OK;
3428   }
3429
3430   put = (struct PeerPutMessage *) message;
3431   putlen = ntohl (put->put_path_length);
3432   if ((msize <
3433        sizeof (struct PeerPutMessage) +
3434        putlen * sizeof (struct GNUNET_PeerIdentity)) ||
3435       (putlen >
3436        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
3437   {
3438     GNUNET_break_op (0);
3439     return GNUNET_OK;
3440   }
3441   DEBUG("GET FOR DATA_SIZE = %lu\n",msize);
3442   GNUNET_STATISTICS_update (GDS_stats,
3443                             gettext_noop
3444                             ("# Bytes received from other peers"), (int64_t) msize,
3445                             GNUNET_NO);
3446   
3447   best_known_dest = put->best_known_destination;
3448   put_path = (struct GNUNET_PeerIdentity *) &put[1];
3449   payload = &put_path[putlen];
3450   options = ntohl (put->options);
3451   intermediate_trail_id = put->intermediate_trail_id;
3452   payload_size = msize - (sizeof (struct PeerPutMessage) +
3453                           putlen * sizeof (struct GNUNET_PeerIdentity));
3454
3455   switch (GNUNET_BLOCK_get_key (GDS_block_context, ntohl (put->block_type),
3456                                 payload, payload_size, &test_key))
3457   {
3458     case GNUNET_YES:
3459       if (0 != memcmp (&test_key, &put->key, sizeof (struct GNUNET_HashCode)))
3460       {
3461         char *put_s = GNUNET_strdup (GNUNET_h2s_full (&put->key));
3462         GNUNET_break_op (0);
3463         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3464                     "PUT with key `%s' for block with key %s\n",
3465                      put_s, GNUNET_h2s_full (&test_key));
3466         GNUNET_free (put_s);
3467         return GNUNET_OK;
3468       }
3469     break;
3470     case GNUNET_NO:
3471       GNUNET_break_op (0);
3472       return GNUNET_OK;
3473     case GNUNET_SYSERR:
3474       /* cannot verify, good luck */
3475       break;
3476   }
3477
3478    if (ntohl (put->block_type) == GNUNET_BLOCK_TYPE_REGEX) /* FIXME: do for all tpyes */
3479   {
3480     switch (GNUNET_BLOCK_evaluate (GDS_block_context,
3481                                    ntohl (put->block_type),
3482                                    NULL,    /* query */
3483                                    NULL, 0, /* bloom filer */
3484                                    NULL, 0, /* xquery */
3485                                    payload, payload_size))
3486     {
3487     case GNUNET_BLOCK_EVALUATION_OK_MORE:
3488     case GNUNET_BLOCK_EVALUATION_OK_LAST:
3489       break;
3490
3491     case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE:
3492     case GNUNET_BLOCK_EVALUATION_RESULT_INVALID:
3493     case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT:
3494     case GNUNET_BLOCK_EVALUATION_REQUEST_VALID:
3495     case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID:
3496     case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED:
3497     default:
3498       GNUNET_break_op (0);
3499       return GNUNET_OK;
3500     }
3501   }
3502
3503   memcpy (&key_value, &(put->key), sizeof (uint64_t));
3504   if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&best_known_dest, &my_identity)))
3505   {
3506     next_hop = GDS_ROUTING_get_next_hop (intermediate_trail_id,
3507                                          GDS_ROUTING_SRC_TO_DEST);
3508     if (NULL == next_hop)
3509     {
3510       DEBUG(" NO ENTRY FOUND IN %s ROUTING TABLE for trail id %s, line",
3511             GNUNET_i2s(&my_identity), GNUNET_h2s(&intermediate_trail_id), __LINE__);
3512       GNUNET_STATISTICS_update (GDS_stats,
3513                                 gettext_noop ("# Next hop to forward the packet not found "
3514                                 "trail setup request, packet dropped."),
3515                                 1, GNUNET_NO);
3516       GNUNET_break_op (0);
3517       return GNUNET_OK;
3518     }
3519   }
3520   else
3521   {
3522     struct Closest_Peer successor;
3523     key_value = GNUNET_ntohll (key_value);
3524     successor = find_successor (key_value, GDS_FINGER_TYPE_NON_PREDECESSOR);
3525     next_hop = GNUNET_new (struct GNUNET_PeerIdentity);
3526     *next_hop = successor.next_hop;
3527     intermediate_trail_id = successor.trail_id;
3528     best_known_dest = successor.best_known_destination;
3529   }
3530   
3531   /* Check if you are already a part of put path. */
3532   unsigned int i;
3533   for (i = 0; i < putlen; i++)
3534   {
3535     if(0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &put_path[i]))
3536     {
3537       putlen = i;
3538       break;
3539     }
3540   }
3541     
3542   /* Add yourself to the list. */
3543   struct GNUNET_PeerIdentity pp[putlen + 1];
3544   if (0 != (options & GNUNET_DHT_RO_RECORD_ROUTE))
3545   {
3546     memcpy (pp, put_path, putlen * sizeof (struct GNUNET_PeerIdentity));
3547     pp[putlen] = my_identity;
3548     putlen++;
3549   }
3550   else
3551     putlen = 0;
3552
3553   GDS_CLIENTS_process_put (options,
3554                            ntohl (put->block_type),
3555                            ntohl (put->hop_count),
3556                            ntohl (put->desired_replication_level),
3557                            putlen, pp,
3558                            GNUNET_TIME_absolute_ntoh (put->expiration_time),
3559                            &put->key,
3560                            payload,
3561                            payload_size);
3562
3563   /* I am the final destination */
3564   if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &best_known_dest))
3565   {
3566     DEBUG("PUT destination is me = %s,KEY = %s\n",GNUNET_i2s(&my_identity),GNUNET_h2s(&(put->key)));
3567     GDS_DATACACHE_handle_put (GNUNET_TIME_absolute_ntoh (put->expiration_time),
3568                               &(put->key),putlen, pp, ntohl (put->block_type),
3569                               payload_size, payload);
3570   }
3571   else
3572   {
3573     GDS_NEIGHBOURS_send_put (&put->key,
3574                              ntohl (put->block_type),ntohl (put->options),
3575                              ntohl (put->desired_replication_level),
3576                              best_known_dest, intermediate_trail_id, next_hop,
3577                              ntohl (put->hop_count), putlen, pp,
3578                              GNUNET_TIME_absolute_ntoh (put->expiration_time),
3579                              payload, payload_size);
3580    }
3581   return GNUNET_OK;
3582 }
3583
3584
3585 /**
3586  * FIXME: Check for loop in the request. If you already are part of get path,
3587  * then you need to reset the get path length.
3588  * Core handler for p2p get requests.
3589  *
3590  * @param cls closure
3591  * @param peer sender of the request
3592  * @param message message
3593  * @return #GNUNET_OK to keep the connection open,
3594  *         #GNUNET_SYSERR to close it (signal serious error)
3595  */
3596 static int
3597 handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer,
3598                     const struct GNUNET_MessageHeader *message)
3599 {
3600   const struct PeerGetMessage *get;
3601   const struct GNUNET_PeerIdentity *get_path;
3602   struct GNUNET_PeerIdentity best_known_dest;
3603   struct GNUNET_HashCode intermediate_trail_id;
3604   struct GNUNET_PeerIdentity *next_hop;
3605   uint32_t get_length;
3606   uint64_t key_value;
3607   size_t msize;
3608
3609 #if ENABLE_MALICIOUS
3610   if(1 == act_malicious)
3611   {
3612     DEBUG("I am malicious,dropping get request. \n");
3613     return GNUNET_OK;
3614   }
3615 #endif
3616   
3617   msize = ntohs (message->size);
3618   if (msize < sizeof (struct PeerGetMessage))
3619   {
3620     GNUNET_break_op (0);
3621     return GNUNET_YES;
3622   }
3623
3624   get = (const struct PeerGetMessage *)message;
3625   get_length = ntohl (get->get_path_length);
3626   best_known_dest = get->best_known_destination;
3627   intermediate_trail_id = get->intermediate_trail_id;
3628   get_path = (const struct GNUNET_PeerIdentity *)&get[1];
3629
3630   if ((msize <
3631        sizeof (struct PeerGetMessage) +
3632        get_length * sizeof (struct GNUNET_PeerIdentity)) ||
3633        (get_length >
3634         GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
3635   {
3636     GNUNET_break_op (0);
3637     return GNUNET_YES;
3638   }
3639   DEBUG("PUT FOR DATA_SIZE = %lu\n",msize);
3640   GNUNET_STATISTICS_update (GDS_stats,
3641                             gettext_noop
3642                             ("# Bytes received from other peers"), msize,
3643                             GNUNET_NO);
3644   
3645   memcpy (&key_value, &(get->key), sizeof (uint64_t));
3646   key_value = GNUNET_ntohll (key_value);
3647   
3648   /* Check if you are already a part of get path. */
3649   unsigned int i;
3650   for (i = 0; i < get_length; i++)
3651   {
3652     if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &get_path[i]))
3653     {
3654       get_length = i;
3655       break;
3656     }
3657   }
3658   
3659   /* Add yourself in the get path. */
3660   struct GNUNET_PeerIdentity gp[get_length + 1];
3661   memcpy (gp, get_path, get_length * sizeof (struct GNUNET_PeerIdentity));
3662   gp[get_length] = my_identity;
3663   get_length = get_length + 1;
3664   GDS_CLIENTS_process_get (get->options, get->block_type,get->hop_count,
3665                            get->desired_replication_level, get->get_path_length,
3666                            gp, &get->key);
3667   
3668   /* I am not the final destination. I am part of trail to reach final dest. */
3669   if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&best_known_dest, &my_identity)))
3670   {
3671     next_hop = GDS_ROUTING_get_next_hop (intermediate_trail_id,
3672                                          GDS_ROUTING_SRC_TO_DEST);
3673     if (NULL == next_hop)
3674     {
3675       DEBUG(" NO ENTRY FOUND IN %s ROUTING TABLE for trail id %s, line",
3676             GNUNET_i2s(&my_identity), GNUNET_h2s(&intermediate_trail_id), __LINE__);
3677       GNUNET_STATISTICS_update (GDS_stats,
3678                                 gettext_noop ("# Next hop to forward the packet not found "
3679                                 "GET request, packet dropped."),
3680                                 1, GNUNET_NO);
3681       GNUNET_break (0);
3682       /* We are not able to proceed further*/
3683       GDS_DATACACHE_handle_get (&(get->key),(get->block_type), NULL, 0, NULL, 0,
3684                                 get_length, gp, &gp[get_length - 2], 
3685                                 &my_identity);
3686       return GNUNET_OK;
3687     }
3688   }
3689   else
3690   {
3691     struct Closest_Peer successor;
3692
3693     successor = find_successor (key_value, GDS_FINGER_TYPE_NON_PREDECESSOR);
3694     next_hop = GNUNET_new (struct GNUNET_PeerIdentity);
3695     *next_hop = successor.next_hop;
3696     best_known_dest = successor.best_known_destination;
3697     intermediate_trail_id = successor.trail_id;
3698   }
3699    
3700   /* I am the final destination. */
3701   if (0 == GNUNET_CRYPTO_cmp_peer_identity(&my_identity, &best_known_dest))
3702   {
3703     DEBUG("GET destination is me = %s,KEY = %s,get_length = %d\n",
3704             GNUNET_i2s(&my_identity),GNUNET_h2s(&(get->key)),get_length);
3705     if (1 == get_length)
3706     {
3707       GDS_DATACACHE_handle_get (&(get->key),(get->block_type), NULL, 0,
3708                                 NULL, 0, 1, &my_identity, NULL,&my_identity);
3709     }
3710     else
3711     {
3712       GDS_DATACACHE_handle_get (&(get->key),(get->block_type), NULL, 0, NULL, 0,
3713                                 get_length, gp, &gp[get_length - 2], 
3714                                 &my_identity);
3715     }
3716   }
3717   else
3718   {
3719     GDS_NEIGHBOURS_send_get (&(get->key), get->block_type, get->options,
3720                              get->desired_replication_level, best_known_dest,
3721                              intermediate_trail_id, next_hop, 0,
3722                              get_length, gp);
3723   }
3724   return GNUNET_YES;
3725 }
3726
3727
3728 /**
3729  * Core handler for get result
3730  * @param cls closure
3731  * @param peer sender of the request
3732  * @param message message
3733  * @return #GNUNET_OK to keep the connection open,
3734  *         #GNUNET_SYSERR to close it (signal serious error)
3735  */
3736 static int
3737 handle_dht_p2p_get_result (void *cls, const struct GNUNET_PeerIdentity *peer,
3738                            const struct GNUNET_MessageHeader *message)
3739 {
3740   const struct PeerGetResultMessage *get_result;
3741   const struct GNUNET_PeerIdentity *get_path;
3742   const struct GNUNET_PeerIdentity *put_path;
3743   const void *payload;
3744   size_t payload_size;
3745   size_t msize;
3746   unsigned int getlen;
3747   unsigned int putlen;
3748   int current_path_index;
3749
3750   msize = ntohs (message->size);
3751   if (msize < sizeof (struct PeerGetResultMessage))
3752   {
3753     GNUNET_break_op (0);
3754     return GNUNET_YES;
3755   }
3756
3757   get_result = (const struct PeerGetResultMessage *)message;
3758   getlen = ntohl (get_result->get_path_length);
3759   putlen = ntohl (get_result->put_path_length);
3760
3761   if ((msize <
3762        sizeof (struct PeerGetResultMessage) +
3763        getlen * sizeof (struct GNUNET_PeerIdentity) +
3764        putlen * sizeof (struct GNUNET_PeerIdentity)) ||
3765       (getlen >
3766        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity) ||
3767       (putlen >
3768          GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity))))
3769   {
3770     GNUNET_break_op (0);
3771     return GNUNET_YES;
3772   }
3773   DEBUG("GET_RESULT  FOR DATA_SIZE = %lu\n",msize);
3774   GNUNET_STATISTICS_update (GDS_stats,
3775                             gettext_noop
3776                             ("# Bytes received from other peers"), msize,
3777                             GNUNET_NO);
3778   
3779   put_path = (const struct GNUNET_PeerIdentity *) &get_result[1];
3780   get_path = &put_path[putlen];
3781   payload = (const void *) &get_path[getlen];
3782   payload_size = msize - (sizeof (struct PeerGetResultMessage) +
3783                          (getlen + putlen) * sizeof (struct GNUNET_PeerIdentity));
3784
3785   if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &(get_path[0]))))
3786   {
3787     GDS_CLIENTS_handle_reply (get_result->expiration_time, &(get_result->key),
3788                               getlen, get_path, putlen,
3789                               put_path, get_result->type, payload_size, payload);
3790     return GNUNET_YES;
3791   }
3792   else
3793   {
3794     current_path_index = search_my_index (get_path, getlen);
3795     if (-1 == current_path_index )
3796     {
3797       DEBUG ("No entry found in get path.\n");
3798       GNUNET_break (0);
3799       return GNUNET_SYSERR;
3800     }
3801     if((getlen + 1) == current_path_index)
3802     {
3803       DEBUG("Present twice in get path. Not allowed. \n");
3804       GNUNET_break (0);
3805       return GNUNET_SYSERR;
3806     }
3807     GDS_NEIGHBOURS_send_get_result (&(get_result->key), get_result->type,
3808                                     &get_path[current_path_index - 1],
3809                                     &(get_result->querying_peer), putlen, put_path,
3810                                     getlen, get_path, get_result->expiration_time,
3811                                     payload, payload_size);
3812     return GNUNET_YES;
3813   }
3814   return GNUNET_SYSERR;
3815 }
3816
3817
3818 /**
3819  * Find the next hop to pass trail setup message. First find the local best known
3820  * hop from your own identity, friends and finger. If you were part of trail,
3821  * then get the next hop from routing table. Compare next_hop from routing table
3822  * and local best known hop, and return the closest one to final_dest_finger_val
3823  * @param final_dest_finger_val 64 bit value of finger identity
3824  * @param intermediate_trail_id If you are part of trail to reach to some other
3825  *                              finger, then it is the trail id to reach to
3826  *                              that finger, else set to 0.
3827  * @param is_predecessor Are we looking for closest successor or predecessor.
3828  * @param current_dest In case you are part of trail, then finger to which
3829  *                     we should forward the message. Else my own identity
3830  * @return Closest Peer for @a final_dest_finger_val
3831  */
3832 static struct Closest_Peer
3833 get_local_best_known_next_hop (uint64_t final_dest_finger_val,
3834                                struct GNUNET_HashCode intermediate_trail_id,
3835                                unsigned int is_predecessor,
3836                                 struct GNUNET_PeerIdentity prev_hop,
3837                                struct GNUNET_PeerIdentity source,
3838                                struct GNUNET_PeerIdentity *current_dest)
3839 {
3840   struct Closest_Peer peer;
3841
3842   /* Find a local best known peer. */
3843   peer = find_successor (final_dest_finger_val, is_predecessor);//FIXME: chnage to better name
3844
3845   /* Am I just a part of a trail towards a finger (current_destination)? */
3846   /* Select best successor among one found locally and current_destination
3847    * that we got from network.*/
3848   if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity, current_dest) &&
3849       0 != GNUNET_CRYPTO_cmp_peer_identity (&peer.best_known_destination,
3850                                             current_dest))
3851   {
3852     struct GNUNET_PeerIdentity closest_peer;
3853
3854     closest_peer = select_closest_peer (&peer.best_known_destination,
3855                                         current_dest,
3856                                         final_dest_finger_val,
3857                                         is_predecessor);
3858
3859     /* Is current dest (end point of the trail of which I am a part) closest_peer? */
3860     if (0 == GNUNET_CRYPTO_cmp_peer_identity (current_dest, &closest_peer))
3861     {
3862       struct GNUNET_PeerIdentity *next_hop;
3863       
3864       next_hop = GDS_ROUTING_get_next_hop (intermediate_trail_id,
3865                                            GDS_ROUTING_SRC_TO_DEST);
3866       /* It may happen that trail teardown message got delayed and hence,
3867          the previous hop sent the message over intermediate trail id.In that
3868          case next_hop could be NULL. */
3869       if(NULL != next_hop)
3870       {
3871          peer.next_hop = *next_hop;
3872          peer.best_known_destination =  *current_dest;
3873          peer.trail_id = intermediate_trail_id;
3874       }
3875     }
3876   }
3877   return peer;
3878 }
3879
3880
3881 /*
3882  * Core handle for PeerTrailSetupMessage.
3883  * @param cls closure
3884  * @param message message
3885  * @param peer peer identity this notification is about
3886  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
3887  */
3888 static int
3889 handle_dht_p2p_trail_setup (void *cls, const struct GNUNET_PeerIdentity *peer,
3890                             const struct GNUNET_MessageHeader *message)
3891 {
3892   const struct PeerTrailSetupMessage *trail_setup;
3893   const struct GNUNET_PeerIdentity *trail_peer_list;
3894   struct GNUNET_PeerIdentity current_dest;
3895   struct FriendInfo *target_friend;
3896   struct GNUNET_PeerIdentity source;
3897   uint64_t final_dest_finger_val;
3898   struct GNUNET_HashCode intermediate_trail_id;
3899   struct GNUNET_HashCode trail_id;
3900   unsigned int is_predecessor;
3901   uint32_t trail_length;
3902   int i;
3903   size_t msize;
3904
3905   msize = ntohs (message->size);
3906   if (msize < sizeof (struct PeerTrailSetupMessage))
3907   {
3908     GNUNET_break_op (0);
3909     return GNUNET_SYSERR;
3910   }
3911
3912   trail_setup = (const struct PeerTrailSetupMessage *) message;
3913   if ((msize - sizeof (struct PeerTrailSetupMessage)) %
3914       sizeof (struct GNUNET_PeerIdentity) != 0)
3915   {
3916     GNUNET_break_op (0);
3917     return GNUNET_OK;
3918   }
3919   trail_length = (msize - sizeof (struct PeerTrailSetupMessage))/
3920                   sizeof (struct GNUNET_PeerIdentity);
3921  
3922   GNUNET_STATISTICS_update (GDS_stats,
3923                             gettext_noop
3924                             ("# Bytes received from other peers"), msize,
3925                             GNUNET_NO);
3926   
3927   trail_peer_list = (const struct GNUNET_PeerIdentity *)&trail_setup[1];
3928   current_dest = trail_setup->best_known_destination;
3929   trail_id = trail_setup->trail_id;
3930   final_dest_finger_val =
3931           GNUNET_ntohll (trail_setup->final_destination_finger_value);
3932   source = trail_setup->source_peer;
3933   is_predecessor = ntohl (trail_setup->is_predecessor);
3934   intermediate_trail_id = trail_setup->intermediate_trail_id;
3935
3936   /* Did the friend insert its ID in the trail list? */
3937   if (trail_length > 0 &&
3938       0 != memcmp (&trail_peer_list[trail_length-1], peer, sizeof (struct GNUNET_PeerIdentity)))
3939   {
3940     GNUNET_break_op (0);
3941     return GNUNET_SYSERR;
3942   }
3943   
3944    /* If I was the source and got the message back, then set trail length to 0.*/
3945   if (0 == GNUNET_CRYPTO_cmp_peer_identity(&my_identity, &source))
3946   {   
3947     trail_length = 0;
3948   }
3949   
3950   /* Check if you are friend of source. */
3951   if (trail_length >= 1)
3952   {
3953     if(NULL != GNUNET_CONTAINER_multipeermap_get (friend_peermap, &source))
3954     {
3955       /* If I am a friend, then I can be the first contact, so make
3956        trail length 0. We are going to add ourself later in the code.*/
3957       trail_length = 0;
3958     }
3959   }
3960   
3961   /* Check if you are present in the trail seen so far? */
3962   for (i = 0; i < trail_length ; i++)
3963   {
3964     if(0 == GNUNET_CRYPTO_cmp_peer_identity(&trail_peer_list[i],&my_identity))
3965     {
3966       trail_length = i; /* Check that you add yourself again */
3967       break;
3968     }
3969   }
3970
3971   /* Is my routing table full?  */
3972   if (GNUNET_YES == GDS_ROUTING_threshold_reached())
3973   {
3974     GNUNET_assert (NULL !=
3975                   (target_friend =
3976                    GNUNET_CONTAINER_multipeermap_get (friend_peermap, peer)));
3977     GDS_NEIGHBOURS_send_trail_rejection (source, final_dest_finger_val,
3978                                          my_identity, is_predecessor,
3979                                          trail_peer_list, trail_length,
3980                                          trail_id, target_friend,
3981                                          CONGESTION_TIMEOUT);
3982     return GNUNET_OK;
3983   }
3984
3985   /* Get the next hop to forward the trail setup request. */
3986   struct Closest_Peer next_peer =
3987           get_local_best_known_next_hop (final_dest_finger_val,
3988                                          intermediate_trail_id,
3989                                          is_predecessor,
3990                                          *peer,
3991                                          source,
3992                                          &current_dest);
3993
3994   /* Am I the final destination? */
3995   if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&next_peer.best_known_destination,
3996                                              &my_identity)))
3997   {
3998     if(0 == GNUNET_CRYPTO_cmp_peer_identity (&source, &my_identity))
3999     {
4000       finger_table_add (my_identity, NULL, 0, is_predecessor,
4001                         final_dest_finger_val, trail_id);
4002       return GNUNET_OK;
4003     }
4004     
4005     if (NULL != GNUNET_CONTAINER_multipeermap_get (friend_peermap,
4006                                                    &source))
4007     {
4008       trail_length = 0;
4009     }
4010     
4011     if (trail_length > 0)
4012       target_friend = 
4013               GNUNET_CONTAINER_multipeermap_get (friend_peermap, 
4014                                                  &trail_peer_list[trail_length-1]);
4015     else
4016       target_friend = 
4017               GNUNET_CONTAINER_multipeermap_get (friend_peermap, &source);
4018     
4019     if (NULL == target_friend)
4020     {
4021       GNUNET_break_op (0);
4022       return GNUNET_SYSERR;
4023     }
4024     GDS_ROUTING_add (trail_id, target_friend->id, my_identity);
4025     GDS_NEIGHBOURS_send_trail_setup_result (source,
4026                                             my_identity,
4027                                             target_friend, trail_length,
4028                                             trail_peer_list,
4029                                             is_predecessor,
4030                                             final_dest_finger_val,trail_id);
4031   }
4032   else /* I'm not the final destination. */
4033   {
4034     GNUNET_assert (NULL !=
4035                    (target_friend =
4036                       GNUNET_CONTAINER_multipeermap_get (friend_peermap,
4037                                                          &next_peer.next_hop)));
4038
4039     if (0 != GNUNET_CRYPTO_cmp_peer_identity(&my_identity, &source))
4040     {
4041       /* Add yourself to list of peers. */
4042       struct GNUNET_PeerIdentity peer_list[trail_length + 1];
4043
4044       memcpy (peer_list, trail_peer_list,
4045               trail_length * sizeof (struct GNUNET_PeerIdentity));
4046       peer_list[trail_length] = my_identity;
4047       GDS_NEIGHBOURS_send_trail_setup (source,
4048                                        final_dest_finger_val,
4049                                        next_peer.best_known_destination,
4050                                        target_friend, trail_length + 1, peer_list,
4051                                        is_predecessor, trail_id,
4052                                        next_peer.trail_id);
4053     }
4054     else
4055         GDS_NEIGHBOURS_send_trail_setup (source,
4056                                          final_dest_finger_val,
4057                                          next_peer.best_known_destination,
4058                                          target_friend, 0, NULL,
4059                                          is_predecessor, trail_id,
4060                                          next_peer.trail_id);
4061   }
4062   return GNUNET_OK;
4063 }
4064
4065
4066 /**
4067  * Core handle for p2p trail setup result messages.
4068  * @param closure
4069  * @param message message
4070  * @param peer sender of this message.
4071  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
4072  */
4073 static int
4074 handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *peer,
4075                                   const struct GNUNET_MessageHeader *message)
4076 {
4077   const struct PeerTrailSetupResultMessage *trail_result;
4078   const struct GNUNET_PeerIdentity *trail_peer_list;
4079   struct GNUNET_PeerIdentity next_hop;
4080   struct FriendInfo *target_friend;
4081   struct GNUNET_PeerIdentity querying_peer;
4082   struct GNUNET_PeerIdentity finger_identity;
4083   uint32_t trail_length;
4084   uint64_t ulitmate_destination_finger_value;
4085   uint32_t is_predecessor;
4086   struct GNUNET_HashCode trail_id;
4087   int my_index;
4088   size_t msize;
4089
4090   msize = ntohs (message->size);
4091   if (msize < sizeof (struct PeerTrailSetupResultMessage))
4092   {
4093     GNUNET_break_op (0);
4094     return GNUNET_YES;
4095   }
4096
4097   trail_result = (const struct PeerTrailSetupResultMessage *) message;
4098   if ((msize - sizeof (struct PeerTrailSetupResultMessage)) %
4099       sizeof (struct GNUNET_PeerIdentity) != 0)
4100   {
4101     GNUNET_break_op (0);
4102     return GNUNET_OK;
4103   }
4104   trail_length = (msize - sizeof (struct PeerTrailSetupResultMessage))/
4105                   sizeof (struct GNUNET_PeerIdentity);
4106   
4107   GNUNET_STATISTICS_update (GDS_stats,
4108                             gettext_noop
4109                             ("# Bytes received from other peers"), msize,
4110                             GNUNET_NO);
4111   
4112   is_predecessor = ntohl (trail_result->is_predecessor);
4113   querying_peer = trail_result->querying_peer;
4114   finger_identity = trail_result->finger_identity;
4115   trail_id = trail_result->trail_id;
4116   trail_peer_list = (const struct GNUNET_PeerIdentity *) &trail_result[1];
4117   ulitmate_destination_finger_value =
4118           GNUNET_ntohll (trail_result->ulitmate_destination_finger_value);
4119
4120   /* Am I the one who initiated the query? */
4121   if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&querying_peer, &my_identity)))
4122   {
4123     /* Check that you got the message from the correct peer. */
4124     if (trail_length > 0)
4125     {
4126       GNUNET_assert(0 == GNUNET_CRYPTO_cmp_peer_identity (&trail_peer_list[0],
4127                                                           peer));
4128     }
4129     else
4130     {
4131       GNUNET_assert(0 == GNUNET_CRYPTO_cmp_peer_identity (&finger_identity,
4132                                                           peer));
4133     }
4134     GDS_ROUTING_add (trail_id, my_identity, *peer);
4135     finger_table_add (finger_identity, trail_peer_list, trail_length,
4136                       is_predecessor, ulitmate_destination_finger_value, trail_id);
4137     return GNUNET_YES;
4138   }
4139
4140   /* Get my location in the trail. */
4141   my_index = search_my_index (trail_peer_list, trail_length);
4142   if (-1 == my_index)
4143   {
4144     DEBUG ("Not found in trail\n");
4145     GNUNET_break_op(0);
4146     return GNUNET_SYSERR;
4147   }
4148   //TODO; return -2.
4149   if ((trail_length + 1) == my_index)
4150   {
4151     DEBUG ("Found twice in trail.\n");
4152     GNUNET_break_op(0);
4153     return GNUNET_SYSERR;
4154   }
4155   
4156   //TODO; Refactor code here and above to check if sender peer is correct
4157   if (my_index == 0)
4158   {
4159     if(trail_length > 1)
4160       GNUNET_assert(0 == GNUNET_CRYPTO_cmp_peer_identity (&trail_peer_list[1],
4161                                                           peer));
4162     else
4163       GNUNET_assert(0 == GNUNET_CRYPTO_cmp_peer_identity (&finger_identity,
4164                                                           peer));
4165     next_hop = trail_result->querying_peer;
4166   }
4167   else
4168   {
4169     if(my_index == trail_length - 1)
4170     {
4171       GNUNET_assert(0 == 
4172                     GNUNET_CRYPTO_cmp_peer_identity (&finger_identity,
4173                                                      peer));  
4174     }
4175     else
4176       GNUNET_assert(0 == 
4177                     GNUNET_CRYPTO_cmp_peer_identity (&trail_peer_list[my_index + 1],
4178                                                       peer));
4179     next_hop = trail_peer_list[my_index - 1];
4180   }
4181   
4182   target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
4183   if (NULL == target_friend)
4184   {
4185     GNUNET_break_op (0);
4186     return GNUNET_SYSERR;
4187   }
4188   GDS_ROUTING_add (trail_id, next_hop, *peer);
4189   GDS_NEIGHBOURS_send_trail_setup_result (querying_peer, finger_identity,
4190                                           target_friend, trail_length, trail_peer_list,
4191                                           is_predecessor,
4192                                           ulitmate_destination_finger_value,
4193                                           trail_id);
4194   return GNUNET_OK;
4195 }
4196
4197
4198 /**
4199  * Invert the trail.
4200  * @param trail Trail to be inverted
4201  * @param trail_length Total number of peers in the trail.
4202  * @return Updated trail
4203  */
4204 static struct GNUNET_PeerIdentity *
4205 invert_trail (const struct GNUNET_PeerIdentity *trail,
4206               unsigned int trail_length)
4207 {
4208   int i;
4209   int j;
4210   struct GNUNET_PeerIdentity *inverted_trail;
4211
4212   inverted_trail = GNUNET_malloc (sizeof(struct GNUNET_PeerIdentity) *
4213                                   trail_length);
4214   i = 0;
4215   j = trail_length - 1;
4216   while (i < trail_length)
4217   {
4218     inverted_trail[i] = trail[j];
4219     i++;
4220     j--;
4221   }
4222
4223   GNUNET_assert(NULL != GNUNET_CONTAINER_multipeermap_get(friend_peermap,
4224                                                           &inverted_trail[0]));
4225   return inverted_trail;
4226 }
4227
4228
4229 /**
4230  * Return the shortest trail among all the trails to reach to finger from me.
4231  * @param finger Finger
4232  * @param shortest_trail_length[out] Trail length of shortest trail from me
4233  *                                   to @a finger
4234  * @return Shortest trail.
4235  */
4236 static struct GNUNET_PeerIdentity *
4237 get_shortest_trail (struct FingerInfo *finger,
4238                     unsigned int *trail_length)
4239 {
4240   struct Trail *trail;
4241   unsigned int flag = 0;
4242   unsigned int shortest_trail_index = 0;
4243   int shortest_trail_length = -1;
4244   struct Trail_Element *trail_element;
4245   struct GNUNET_PeerIdentity *trail_list;
4246   unsigned int i;
4247
4248   trail = GNUNET_new (struct Trail);
4249
4250   /* Get the shortest trail to reach to current successor. */
4251   for (i = 0; i < finger->trails_count; i++)
4252   {
4253     trail = &finger->trail_list[i];
4254
4255     if (0 == flag)
4256     {
4257       shortest_trail_index = i;
4258       shortest_trail_length = trail->trail_length;
4259       flag = 1;
4260       continue;
4261     }
4262
4263     if (shortest_trail_length > trail->trail_length)
4264     {
4265       shortest_trail_index = i;
4266       shortest_trail_length = trail->trail_length;
4267     }
4268     continue;
4269   }
4270
4271   /* Copy the shortest trail and return. */
4272   trail = &finger->trail_list[shortest_trail_index];
4273   trail_element = trail->trail_head;
4274
4275   trail_list = GNUNET_malloc (sizeof(struct GNUNET_PeerIdentity)*
4276                               shortest_trail_length);
4277
4278   for(i = 0; i < shortest_trail_length; i++,trail_element = trail_element->next)
4279   {
4280     trail_list[i] = trail_element->peer;
4281   }
4282
4283   GNUNET_assert(shortest_trail_length != -1);
4284
4285   *trail_length = shortest_trail_length;
4286   return trail_list;
4287 }
4288
4289
4290 /**
4291  * Check if trail_1 and trail_2 have any common element. If yes then join 
4292  * them at common element. trail_1 always preceeds trail_2 in joined trail. 
4293  * @param trail_1 Trail from source to me, NOT including endpoints.
4294  * @param trail_1_len Total number of peers @a trail_1
4295  * @param trail_2 Trail from me to current predecessor, NOT including endpoints.
4296  * @param trail_2_len Total number of peers @a trail_2
4297  * @param joined_trail_len Total number of peers in combined trail of trail_1
4298  *                          trail_2.
4299  * @return Joined trail.
4300  */
4301 static struct GNUNET_PeerIdentity *
4302 check_for_duplicate_entries (const struct GNUNET_PeerIdentity *trail_1,
4303                              unsigned int trail_1_len,
4304                              struct GNUNET_PeerIdentity *trail_2,
4305                              unsigned int trail_2_len,
4306                              unsigned int *joined_trail_len)
4307 {
4308   struct GNUNET_PeerIdentity *joined_trail;
4309   unsigned int i;
4310   unsigned int j;
4311   unsigned int k;
4312   
4313   for (i = 0; i < trail_1_len; i++)
4314   {
4315     for (j = 0; j < trail_2_len; j++)
4316     {
4317       if(0 != GNUNET_CRYPTO_cmp_peer_identity (&trail_1[i],&trail_2[j]))
4318         continue;
4319       
4320       *joined_trail_len = i + (trail_2_len - j);
4321       joined_trail = GNUNET_malloc (*joined_trail_len * 
4322                                     sizeof(struct GNUNET_PeerIdentity));
4323       
4324       
4325       /* Copy all the elements from 0 to i into joined_trail. */
4326       for(k = 0; k < ( i+1); k++)
4327       {
4328         joined_trail[k] = trail_1[k];
4329       }
4330       
4331       /* Increment j as entry stored is same as entry stored at i*/
4332       j = j+1;
4333       
4334       /* Copy all the elements from j to trail_2_len-1 to joined trail.*/
4335       while(k <= (*joined_trail_len - 1))
4336       {
4337         joined_trail[k] = trail_2[j];
4338         j++;
4339         k++;
4340       }
4341       
4342       return joined_trail;
4343     }
4344   }
4345  
4346   /* Here you should join the  trails. */
4347   *joined_trail_len = trail_1_len + trail_2_len + 1;
4348   joined_trail = GNUNET_malloc (*joined_trail_len * 
4349                                 sizeof(struct GNUNET_PeerIdentity));
4350   
4351   
4352   for(i = 0; i < trail_1_len;i++)
4353   {
4354     joined_trail[i] = trail_1[i];
4355   }
4356   
4357   joined_trail[i] = my_identity;
4358   i++;
4359   
4360   for (j = 0; i < *joined_trail_len; i++,j++)
4361   {
4362     joined_trail[i] = trail_2[j];
4363   }
4364   
4365   return joined_trail;
4366 }
4367
4368
4369 /**
4370  * Return the trail from source to my current predecessor. Check if source
4371  * is already part of the this trail, if yes then return the shorten trail.
4372  * @param current_trail Trail from source to me, NOT including the endpoints.
4373  * @param current_trail_length Number of peers in @a current_trail.
4374  * @param trail_src_to_curr_pred_length[out] Number of peers in trail from
4375  *                                           source to my predecessor, NOT including
4376  *                                           the endpoints.
4377  * @return Trail from source to my predecessor.
4378  */
4379 static struct GNUNET_PeerIdentity *
4380 get_trail_src_to_curr_pred (struct GNUNET_PeerIdentity source_peer,
4381                             const struct GNUNET_PeerIdentity *trail_src_to_me,
4382                             unsigned int trail_src_to_me_len,
4383                             unsigned int *trail_src_to_curr_pred_length)
4384 {
4385   struct GNUNET_PeerIdentity *trail_me_to_curr_pred;
4386   struct GNUNET_PeerIdentity *trail_src_to_curr_pred;
4387   unsigned int trail_me_to_curr_pred_length;
4388   struct FingerInfo *current_predecessor;
4389   int i;
4390   unsigned int j;
4391
4392   current_predecessor = &finger_table[PREDECESSOR_FINGER_ID];
4393   
4394   /* Check if trail_src_to_me contains current_predecessor. */
4395   for (i = 0; i < trail_src_to_me_len; i++)
4396   {
4397     if(0 != GNUNET_CRYPTO_cmp_peer_identity(&trail_src_to_me[i],
4398                                             &current_predecessor->finger_identity))
4399         continue;
4400       
4401       
4402     *trail_src_to_curr_pred_length = i;
4403     
4404     if(0 == i)
4405       return NULL;
4406     
4407      trail_src_to_curr_pred = GNUNET_malloc (*trail_src_to_curr_pred_length *
4408                                               sizeof(struct GNUNET_PeerIdentity));
4409      for(j = 0; j < i;j++)
4410        trail_src_to_curr_pred[j] = trail_src_to_me[j];
4411      return trail_src_to_curr_pred;
4412   }
4413
4414  
4415   trail_me_to_curr_pred = get_shortest_trail (current_predecessor,
4416                                               &trail_me_to_curr_pred_length);
4417   
4418   /* Check if trail contains the source_peer. */
4419   for(i = trail_me_to_curr_pred_length - 1; i >= 0; i--)
4420   {
4421     if(0 != GNUNET_CRYPTO_cmp_peer_identity (&source_peer,
4422                                              &trail_me_to_curr_pred[i]))
4423       continue; 
4424     
4425      /* Source is NOT part of trail. */
4426      i = i+1;
4427
4428      /* Source is the last element in the trail to reach to my pred.
4429          Source is direct friend of the pred. */
4430      if (trail_me_to_curr_pred_length == i)
4431      {
4432         *trail_src_to_curr_pred_length = 0;
4433         return NULL;
4434      }
4435      
4436      *trail_src_to_curr_pred_length = trail_me_to_curr_pred_length - i;
4437      trail_src_to_curr_pred = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)*
4438                                               *trail_src_to_curr_pred_length);
4439      
4440      for(j = 0; j < *trail_src_to_curr_pred_length; i++,j++)
4441      {
4442        trail_src_to_curr_pred[j] = trail_me_to_curr_pred[i];
4443      }
4444      GNUNET_free_non_null(trail_me_to_curr_pred);
4445      return trail_src_to_curr_pred;
4446   }
4447   
4448   unsigned int len;
4449   trail_src_to_curr_pred = check_for_duplicate_entries (trail_src_to_me, 
4450                                                         trail_src_to_me_len,
4451                                                         trail_me_to_curr_pred,
4452                                                         trail_me_to_curr_pred_length,
4453                                                         &len); 
4454   *trail_src_to_curr_pred_length = len;
4455   GNUNET_free_non_null(trail_me_to_curr_pred);
4456   return trail_src_to_curr_pred;
4457 }
4458
4459
4460 /**
4461  * Add finger as your predecessor. To add, first generate a new trail id, invert
4462  * the trail to get the trail from me to finger, add an entry in your routing
4463  * table, send add trail message to peers which are part of trail from me to
4464  * finger and add finger in finger table.
4465  * @param finger
4466  * @param trail
4467  * @param trail_length
4468  */
4469 static void
4470 update_predecessor (struct GNUNET_PeerIdentity finger,
4471                     struct GNUNET_PeerIdentity *trail,
4472                     unsigned int trail_length)
4473 {
4474   struct GNUNET_HashCode trail_to_new_predecessor_id;
4475   struct GNUNET_PeerIdentity *trail_to_new_predecessor;
4476   struct FriendInfo *target_friend;
4477
4478   /* Generate trail id for trail from me to new predecessor = finger. */
4479   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG,
4480                               &trail_to_new_predecessor_id,
4481                               sizeof (trail_to_new_predecessor_id));
4482
4483   /* Finger is a friend. */
4484   if (trail_length == 0)
4485   {
4486     trail_to_new_predecessor = NULL;
4487     GDS_ROUTING_add (trail_to_new_predecessor_id, my_identity, finger);
4488     GNUNET_assert (NULL != (target_friend =
4489                             GNUNET_CONTAINER_multipeermap_get (friend_peermap,
4490                                                                &finger)));
4491   }
4492   else
4493   {
4494     /* Invert the trail to get the trail from me to finger, NOT including the
4495        endpoints.*/
4496     GNUNET_assert(NULL != GNUNET_CONTAINER_multipeermap_get(friend_peermap,
4497                                                             &trail[trail_length-1]));
4498   
4499     trail_to_new_predecessor = invert_trail (trail, trail_length);
4500     
4501     /* Add an entry in your routing table. */
4502     GDS_ROUTING_add (trail_to_new_predecessor_id,
4503                      my_identity,
4504                      trail_to_new_predecessor[0]);
4505
4506     GNUNET_assert (NULL != (target_friend =
4507                    GNUNET_CONTAINER_multipeermap_get (friend_peermap,
4508                                                       &trail_to_new_predecessor[0])));
4509     GNUNET_assert (NULL != (
4510                    GNUNET_CONTAINER_multipeermap_get (friend_peermap,
4511                                                       &trail[trail_length - 1])));
4512   }
4513
4514   /* Add entry in routing table of all peers that are part of trail from me
4515      to finger, including finger. */
4516   GDS_NEIGHBOURS_send_add_trail (my_identity,
4517                                  finger,
4518                                  trail_to_new_predecessor_id,
4519                                  trail_to_new_predecessor,
4520                                  trail_length,
4521                                  target_friend);
4522
4523   add_new_finger (finger, trail_to_new_predecessor, trail_length,
4524                   trail_to_new_predecessor_id, PREDECESSOR_FINGER_ID);
4525   GNUNET_free_non_null(trail_to_new_predecessor);
4526 }
4527
4528
4529 /*
4530  * Check if you already have a predecessor. If not then add finger as your
4531  * predecessor. If you have predecessor, then compare two peer identites.
4532  * If finger is correct predecessor, then remove the old entry, add finger in
4533  * finger table and send add_trail message to add the trail in the routing
4534  * table of all peers which are part of trail to reach from me to finger.
4535  * @param finger New peer which may be our predecessor.
4536  * @param trail List of peers to reach from @finger to me.
4537  * @param trail_length Total number of peer in @a trail.
4538  */
4539 static void
4540 compare_and_update_predecessor (struct GNUNET_PeerIdentity finger,
4541                                 struct GNUNET_PeerIdentity *trail,
4542                                 unsigned int trail_length)
4543 {
4544   struct FingerInfo *current_predecessor;
4545   struct GNUNET_PeerIdentity closest_peer;
4546   uint64_t predecessor_value;
4547   unsigned int is_predecessor = 1;
4548
4549   current_predecessor = &finger_table[PREDECESSOR_FINGER_ID];
4550   GNUNET_assert (0 != GNUNET_CRYPTO_cmp_peer_identity (&finger, &my_identity));
4551
4552   /* No predecessor. Add finger as your predecessor. */
4553   if (GNUNET_NO == current_predecessor->is_present)
4554   {
4555     update_predecessor (finger, trail, trail_length);
4556     return;
4557   }
4558   
4559   if (0 == GNUNET_CRYPTO_cmp_peer_identity (&current_predecessor->finger_identity,
4560                                             &finger))
4561   {
4562     return;
4563   }
4564
4565   predecessor_value = compute_finger_identity_value (PREDECESSOR_FINGER_ID);
4566   closest_peer = select_closest_peer (&finger,
4567                                       &current_predecessor->finger_identity,
4568                                       predecessor_value, is_predecessor);
4569
4570   /* Finger is the closest predecessor. Remove the existing one and add the new
4571      one. */
4572   if (0 == GNUNET_CRYPTO_cmp_peer_identity(&closest_peer, &finger))
4573   {
4574     remove_existing_finger (current_predecessor, PREDECESSOR_FINGER_ID);
4575     update_predecessor (finger, trail, trail_length);
4576     return;
4577   }
4578   return;
4579 }
4580
4581
4582 /*
4583  * Core handle for p2p verify successor messages.
4584  * @param cls closure
4585  * @param message message
4586  * @param peer peer identity this notification is about
4587  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
4588  */
4589 static int
4590 handle_dht_p2p_verify_successor(void *cls,
4591                                 const struct GNUNET_PeerIdentity *peer,
4592                                 const struct GNUNET_MessageHeader *message)
4593 {
4594   const struct PeerVerifySuccessorMessage *vsm;
4595   struct GNUNET_HashCode trail_id;
4596   struct GNUNET_PeerIdentity successor;
4597   struct GNUNET_PeerIdentity source_peer;
4598   struct GNUNET_PeerIdentity *trail;
4599   struct GNUNET_PeerIdentity *next_hop;
4600   struct FingerInfo current_predecessor;
4601   struct FriendInfo *target_friend;
4602   unsigned int trail_src_to_curr_pred_len = 0;
4603   struct GNUNET_PeerIdentity *trail_src_to_curr_pred;
4604   unsigned int trail_length;
4605   size_t msize;
4606   
4607   msize = ntohs (message->size);
4608
4609   if (msize < sizeof (struct PeerVerifySuccessorMessage))
4610   {
4611     GNUNET_break_op (0);
4612     return GNUNET_YES;
4613   }
4614
4615   vsm = (const struct PeerVerifySuccessorMessage *) message;
4616   trail_length = (msize - sizeof (struct PeerVerifySuccessorMessage))/
4617                   sizeof (struct GNUNET_PeerIdentity);
4618   if ((msize - sizeof (struct PeerVerifySuccessorMessage)) %
4619       sizeof (struct GNUNET_PeerIdentity) != 0)
4620   {
4621     GNUNET_break_op (0);
4622     return GNUNET_OK;
4623   }
4624   
4625   GNUNET_STATISTICS_update (GDS_stats,
4626                             gettext_noop
4627                             ("# Bytes received from other peers"), msize,
4628                             GNUNET_NO);
4629   
4630   trail_id = vsm->trail_id;
4631   source_peer = vsm->source_peer;
4632   successor = vsm->successor;
4633   trail = (struct GNUNET_PeerIdentity *)&vsm[1];
4634  
4635   /* I am NOT the successor of source_peer. Pass the message to next_hop on
4636    * the trail. */
4637   if(0 != (GNUNET_CRYPTO_cmp_peer_identity (&successor, &my_identity)))
4638   {
4639     next_hop = GDS_ROUTING_get_next_hop (trail_id, GDS_ROUTING_SRC_TO_DEST);    
4640     if (NULL == next_hop)
4641     {
4642       DEBUG(" NO ENTRY FOUND IN %s ROUTING TABLE for trail id %s, line",
4643             GNUNET_i2s(&my_identity), GNUNET_h2s(&trail_id), __LINE__);
4644       GNUNET_break_op (0);
4645       return GNUNET_OK;
4646     }
4647  
4648     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
4649     
4650     if(NULL == target_friend)
4651     {
4652       GNUNET_break_op(0);
4653       return GNUNET_OK;
4654     }
4655     GDS_NEIGHBOURS_send_verify_successor_message (source_peer, successor,
4656                                                   trail_id, trail, trail_length,
4657                                                   target_friend);
4658     return GNUNET_OK;
4659   }
4660
4661   /* I am the destination of this message. */
4662
4663   /* Check if the source_peer could be our predecessor and if yes then update
4664    * it.  */
4665   compare_and_update_predecessor (source_peer, trail, trail_length);
4666   current_predecessor = finger_table[PREDECESSOR_FINGER_ID];
4667   
4668   /* Is source of this message NOT my predecessor. */
4669   if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&current_predecessor.finger_identity,
4670                                              &source_peer)))
4671   {
4672     trail_src_to_curr_pred = 
4673               get_trail_src_to_curr_pred (source_peer,
4674                                           trail,
4675                                           trail_length,
4676                                           &trail_src_to_curr_pred_len);
4677   }
4678   else
4679   {
4680     trail_src_to_curr_pred_len = trail_length;
4681     unsigned int i;
4682
4683     trail_src_to_curr_pred = 
4684             GNUNET_malloc (sizeof(struct GNUNET_PeerIdentity)
4685                            *trail_src_to_curr_pred_len);
4686     for(i = 0; i < trail_src_to_curr_pred_len; i++)
4687     {
4688       trail_src_to_curr_pred[i] = trail[i];
4689     }
4690   }
4691  
4692   GNUNET_assert (NULL !=
4693                 (target_friend =
4694                  GNUNET_CONTAINER_multipeermap_get (friend_peermap, peer)));
4695   GDS_NEIGHBOURS_send_verify_successor_result (source_peer, my_identity,
4696                                                current_predecessor.finger_identity,
4697                                                trail_id, trail_src_to_curr_pred,
4698                                                trail_src_to_curr_pred_len,
4699                                                GDS_ROUTING_DEST_TO_SRC,
4700                                                target_friend);
4701   GNUNET_free_non_null(trail_src_to_curr_pred);
4702   return GNUNET_OK;
4703 }
4704
4705
4706 /**
4707  * If the trail from me to my probable successor contains a friend not
4708  * at index 0, then we can shorten the trail.
4709  * @param probable_successor Peer which is our probable successor
4710  * @param trail_me_to_probable_successor Peers in path from me to my probable
4711  *                                       successor, NOT including the endpoints.
4712  * @param trail_me_to_probable_successor_len Total number of peers in
4713  *                                           @a trail_me_to_probable_succesor.
4714  * @return Updated trail, if any friend found.
4715  *         Else the trail_me_to_probable_successor.
4716  */
4717 struct GNUNET_PeerIdentity *
4718 check_trail_me_to_probable_succ (struct GNUNET_PeerIdentity probable_successor,
4719                                  const struct GNUNET_PeerIdentity *trail_me_to_probable_successor,
4720                                  unsigned int trail_me_to_probable_successor_len,
4721                                  unsigned int *trail_to_new_successor_length)
4722 {
4723   unsigned int i;
4724   unsigned int j;
4725   struct GNUNET_PeerIdentity *trail_to_new_successor;
4726
4727   /* Probable successor is  a friend */
4728   if (NULL != GNUNET_CONTAINER_multipeermap_get (friend_peermap,
4729                                                  &probable_successor))
4730   {
4731     trail_to_new_successor = NULL;
4732     *trail_to_new_successor_length = 0;
4733     return trail_to_new_successor;
4734   }
4735   
4736   /* Is there any friend of yours in this trail. */
4737   if(trail_me_to_probable_successor_len > 1)
4738   {
4739     for (i = trail_me_to_probable_successor_len - 1; i > 0; i--)
4740     {
4741       if (NULL == GNUNET_CONTAINER_multipeermap_get (friend_peermap,
4742                                                      &trail_me_to_probable_successor[i]))
4743         continue;
4744
4745       *trail_to_new_successor_length = (trail_me_to_probable_successor_len - i);
4746       trail_to_new_successor = GNUNET_malloc (sizeof(struct GNUNET_PeerIdentity)*
4747                                                 *trail_to_new_successor_length);
4748
4749      
4750       for(j = 0;j < *trail_to_new_successor_length;i++,j++)
4751       {
4752         trail_to_new_successor[j] = trail_me_to_probable_successor[i];
4753       }
4754       
4755       return trail_to_new_successor;
4756     }
4757   }
4758
4759   *trail_to_new_successor_length = trail_me_to_probable_successor_len;
4760   return (struct GNUNET_PeerIdentity*)trail_me_to_probable_successor;
4761 }
4762
4763
4764 /**
4765  * Check if the peer which sent us verify successor result message is still ours
4766  * successor or not. If not, then compare existing successor and probable successor.
4767  * In case probable successor is the correct successor, remove the existing
4768  * successor. Add probable successor as new successor. Send notify new successor
4769  * message to new successor.
4770  * @param curr_succ Peer to which we sent the verify successor message. It may
4771  * or may not be our real current successor, as we may have few iterations of
4772  * find finger trail task.
4773  * @param probable_successor Peer which should be our successor accroding to @a 
4774  *                           curr_succ
4775  * @param trail List of peers to reach from me to @a probable successor, NOT including
4776  *              endpoints.
4777  * @param trail_length Total number of peers in @a trail.
4778  */
4779 static void
4780 compare_and_update_successor (struct GNUNET_PeerIdentity curr_succ,
4781                               struct GNUNET_PeerIdentity probable_successor,
4782                               const struct GNUNET_PeerIdentity *trail,
4783                               unsigned int trail_length)
4784 {
4785   struct FingerInfo *current_successor;
4786   struct GNUNET_PeerIdentity closest_peer;
4787   struct GNUNET_HashCode trail_id;
4788   struct GNUNET_PeerIdentity *trail_me_to_probable_succ;
4789   struct FriendInfo *target_friend;
4790   unsigned int trail_me_to_probable_succ_len;
4791   unsigned int is_predecessor = 0;
4792   uint64_t successor_value;
4793
4794   current_successor = &finger_table[0];
4795   successor_value = compute_finger_identity_value(0);
4796
4797   /* If probable successor is same as current_successor, do nothing. */
4798   if(0 == GNUNET_CRYPTO_cmp_peer_identity (&probable_successor,
4799                                            &current_successor->finger_identity))
4800     return;
4801   
4802   closest_peer = select_closest_peer (&probable_successor,
4803                                       &current_successor->finger_identity,
4804                                       successor_value, is_predecessor);
4805
4806   /* If the current_successor in the finger table is closest, then do nothing. */
4807   if (0 == GNUNET_CRYPTO_cmp_peer_identity (&closest_peer ,
4808                                             &current_successor->finger_identity))
4809   {
4810     if ((NULL != GDS_stats))
4811     {
4812       char *my_id_str;
4813       uint64_t succ;
4814       char *key;
4815     
4816       my_id_str = GNUNET_strdup (GNUNET_i2s_full (&my_identity));
4817       memcpy(&succ, &current_successor->finger_identity, sizeof(uint64_t));
4818       GNUNET_asprintf (&key, "XDHT:%s:", my_id_str);
4819       GNUNET_free (my_id_str);
4820       GNUNET_STATISTICS_set (GDS_stats, key, succ, 0);
4821       GNUNET_free (key);
4822     }
4823     return;
4824   }
4825   
4826   /* Probable successor is the closest peer.*/
4827   if(trail_length > 0)
4828   {
4829     GNUNET_assert(NULL != GNUNET_CONTAINER_multipeermap_get(friend_peermap,
4830                                                             &trail[0]));
4831   }
4832   else
4833   {
4834     GNUNET_assert(NULL != GNUNET_CONTAINER_multipeermap_get(friend_peermap,
4835                                                             &probable_successor));
4836   }
4837   
4838   trail_me_to_probable_succ_len = 0;
4839   trail_me_to_probable_succ =
4840           check_trail_me_to_probable_succ (probable_successor,
4841                                            trail, trail_length,
4842                                            &trail_me_to_probable_succ_len);
4843
4844   /* Remove the existing successor. */
4845   remove_existing_finger (current_successor, 0);
4846    /* Generate a new trail id to reach to your new successor. */
4847   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG,
4848                               &trail_id, sizeof (trail_id));
4849
4850   if (trail_me_to_probable_succ_len > 0)
4851   {
4852     GDS_ROUTING_add (trail_id, my_identity, trail_me_to_probable_succ[0]);
4853     GNUNET_assert (NULL !=
4854                   (target_friend =
4855                       GNUNET_CONTAINER_multipeermap_get (friend_peermap,
4856                                                         &trail_me_to_probable_succ[0])));
4857   }
4858   else
4859   {
4860     GDS_ROUTING_add (trail_id, my_identity, probable_successor);
4861     GNUNET_assert (NULL !=
4862                   (target_friend =
4863                    GNUNET_CONTAINER_multipeermap_get (friend_peermap,
4864                                                       &probable_successor)));
4865   }
4866
4867   add_new_finger (probable_successor, trail_me_to_probable_succ,
4868                   trail_me_to_probable_succ_len, trail_id, 0);
4869  
4870   GDS_NEIGHBOURS_send_notify_new_successor (my_identity, probable_successor,
4871                                             trail_me_to_probable_succ,
4872                                             trail_me_to_probable_succ_len,
4873                                             trail_id,
4874                                             target_friend);
4875   return;
4876 }
4877
4878
4879 /*
4880  * FIXME: Check for duplicate elements everywhere when you are making
4881  * trails. 
4882  * Core handle for p2p verify successor result messages.
4883  * @param cls closure
4884  * @param message message
4885  * @param peer peer identity this notification is about
4886  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
4887  */
4888 static int
4889 handle_dht_p2p_verify_successor_result(void *cls,
4890                                        const struct GNUNET_PeerIdentity *peer,
4891                                        const struct GNUNET_MessageHeader *message)
4892 {
4893   const struct PeerVerifySuccessorResultMessage *vsrm;
4894   enum GDS_ROUTING_trail_direction trail_direction;
4895   struct GNUNET_PeerIdentity querying_peer;
4896   struct GNUNET_HashCode trail_id;
4897   struct GNUNET_PeerIdentity *next_hop;
4898   struct FriendInfo *target_friend;
4899   struct GNUNET_PeerIdentity probable_successor;
4900   struct GNUNET_PeerIdentity current_successor;
4901   const struct GNUNET_PeerIdentity *trail;
4902   unsigned int trail_length;
4903   size_t msize;
4904
4905   msize = ntohs (message->size);
4906   /* We send a trail to reach from old successor to new successor, if
4907    * old_successor != new_successor.*/
4908   if (msize < sizeof (struct PeerVerifySuccessorResultMessage))
4909   {
4910     GNUNET_break_op (0);
4911     return GNUNET_YES;
4912   }
4913
4914   vsrm = (const struct PeerVerifySuccessorResultMessage *) message;
4915   trail_length = (msize - sizeof (struct PeerVerifySuccessorResultMessage))/
4916                       sizeof (struct GNUNET_PeerIdentity);
4917
4918   if ((msize - sizeof (struct PeerVerifySuccessorResultMessage)) %
4919       sizeof (struct GNUNET_PeerIdentity) != 0)
4920   {
4921     GNUNET_break_op (0);
4922     return GNUNET_OK;
4923   }
4924
4925   GNUNET_STATISTICS_update (GDS_stats,
4926                             gettext_noop
4927                             ("# Bytes received from other peers"), msize,
4928                             GNUNET_NO);
4929   
4930   trail = (const struct GNUNET_PeerIdentity *) &vsrm[1];
4931   querying_peer = vsrm->querying_peer;
4932   trail_direction = ntohl (vsrm->trail_direction);
4933   trail_id = vsrm->trail_id;
4934   probable_successor = vsrm->probable_successor;
4935   current_successor = vsrm->current_successor;
4936  
4937    verify_successor_next_send_time =
4938                 GNUNET_TIME_STD_BACKOFF(verify_successor_next_send_time);
4939   /* I am the querying_peer. */
4940   if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&querying_peer, &my_identity)))
4941   {
4942     compare_and_update_successor (current_successor,
4943                                   probable_successor, trail, trail_length);
4944     return GNUNET_OK;
4945   }
4946   
4947   /*If you are not the querying peer then pass on the message */
4948   if(NULL == (next_hop =
4949               GDS_ROUTING_get_next_hop (trail_id, trail_direction)))
4950   {
4951     DEBUG(" NO ENTRY FOUND IN %s ROUTING TABLE for trail id %s, line",
4952             GNUNET_i2s(&my_identity), GNUNET_h2s(&trail_id), __LINE__);
4953     GNUNET_break_op(0);
4954     return GNUNET_OK;
4955   }
4956   if (NULL == (target_friend =
4957                  GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop)))
4958   {
4959     GNUNET_break_op(0);
4960     return GNUNET_OK;
4961   }
4962   GDS_NEIGHBOURS_send_verify_successor_result (querying_peer,
4963                                                vsrm->current_successor,
4964                                                probable_successor, trail_id,
4965                                                trail,
4966                                                trail_length,
4967                                                trail_direction, target_friend);
4968   return GNUNET_OK;
4969 }
4970
4971
4972 /*
4973  * Core handle for p2p notify new successor messages.
4974  * @param cls closure
4975  * @param message message
4976  * @param peer peer identity this notification is about
4977  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
4978  */
4979 static int
4980 handle_dht_p2p_notify_new_successor(void *cls,
4981                                     const struct GNUNET_PeerIdentity *peer,
4982                                     const struct GNUNET_MessageHeader *message)
4983 {
4984   const struct PeerNotifyNewSuccessorMessage *nsm;
4985   struct GNUNET_PeerIdentity *trail;
4986   struct GNUNET_PeerIdentity source;
4987   struct GNUNET_PeerIdentity new_successor;
4988   struct GNUNET_HashCode trail_id;
4989   struct GNUNET_PeerIdentity next_hop;
4990   struct FriendInfo *target_friend;
4991   int my_index;
4992   size_t msize;
4993   uint32_t trail_length;
4994
4995   msize = ntohs (message->size);
4996
4997   /* We have the trail to reach from source to new successor. */
4998   if (msize < sizeof (struct PeerNotifyNewSuccessorMessage))
4999   {
5000     GNUNET_break_op (0);
5001     return GNUNET_YES;
5002   }
5003
5004   nsm = (const struct PeerNotifyNewSuccessorMessage *) message;
5005   trail_length = (msize - sizeof (struct PeerNotifyNewSuccessorMessage))/
5006                   sizeof (struct GNUNET_PeerIdentity);
5007   if ((msize - sizeof (struct PeerNotifyNewSuccessorMessage)) %
5008       sizeof (struct GNUNET_PeerIdentity) != 0)
5009   {
5010     GNUNET_break_op (0);
5011     return GNUNET_OK;
5012   }
5013
5014   GNUNET_STATISTICS_update (GDS_stats,
5015                             gettext_noop
5016                             ("# Bytes received from other peers"), msize,
5017                             GNUNET_NO);
5018   
5019   trail = (struct GNUNET_PeerIdentity *) &nsm[1];
5020   source  = nsm->source_peer;
5021   new_successor = nsm->new_successor;
5022   trail_id = nsm->trail_id;
5023  
5024   /* I am the new_successor to source_peer. */
5025   if ( 0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &new_successor))
5026   {
5027     if(trail_length > 0)
5028       GNUNET_assert(0 == GNUNET_CRYPTO_cmp_peer_identity(&trail[trail_length - 1],
5029                                                           peer));
5030     else 
5031       GNUNET_assert(0 == GNUNET_CRYPTO_cmp_peer_identity(&source, peer));
5032   
5033     compare_and_update_predecessor (source, trail, trail_length);
5034     return GNUNET_OK;
5035   }
5036
5037   GNUNET_assert(trail_length > 0);
5038   /* I am part of trail to reach to successor. */
5039   my_index = search_my_index (trail, trail_length);
5040   if (-1 == my_index)
5041   {
5042     DEBUG ("No entry found in trail\n");
5043     GNUNET_break_op (0);
5044     return GNUNET_SYSERR;
5045   }
5046   if((trail_length + 1) == my_index)
5047   {
5048     DEBUG ("Found twice in trail.\n");
5049     GNUNET_break_op (0);
5050     return GNUNET_SYSERR;
5051   }
5052   if ((trail_length-1) == my_index)
5053     next_hop = new_successor;
5054   else
5055     next_hop = trail[my_index + 1];
5056   /* Add an entry in routing table for trail from source to its new successor. */
5057   GNUNET_assert (GNUNET_OK == GDS_ROUTING_add (trail_id, *peer, next_hop));
5058   GNUNET_assert (NULL !=
5059                 (target_friend =
5060                  GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop)));
5061   GDS_NEIGHBOURS_send_notify_new_successor (source, new_successor, trail,
5062                                             trail_length,
5063                                             trail_id, target_friend);
5064   return GNUNET_OK;
5065
5066 }
5067
5068
5069 /**
5070  * Core handler for P2P trail rejection message
5071  * @param cls closure
5072  * @param message message
5073  * @param peer peer identity this notification is about
5074  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
5075  */
5076 static int
5077 handle_dht_p2p_trail_setup_rejection (void *cls,
5078                                       const struct GNUNET_PeerIdentity *peer,
5079                                       const struct GNUNET_MessageHeader *message)
5080 {
5081   const struct PeerTrailRejectionMessage *trail_rejection;
5082   unsigned int trail_length;
5083   const struct GNUNET_PeerIdentity *trail_peer_list;
5084   struct FriendInfo *target_friend;
5085   struct GNUNET_TIME_Relative congestion_timeout;
5086   struct GNUNET_HashCode trail_id;
5087   struct GNUNET_PeerIdentity next_peer;
5088   struct GNUNET_PeerIdentity source;
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   if ((msize - sizeof (struct PeerTrailRejectionMessage)) %
5103       sizeof (struct GNUNET_PeerIdentity) != 0)
5104   {
5105     GNUNET_break_op (0);
5106     return GNUNET_OK;
5107   }
5108   trail_length = (msize - sizeof (struct PeerTrailRejectionMessage))/
5109                   sizeof (struct GNUNET_PeerIdentity);
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   target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, peer);
5126   if (NULL == target_friend)
5127   {
5128     DEBUG ("\nLINE = %d ,No friend found.",__LINE__);
5129     GNUNET_break(0);
5130     return GNUNET_OK;
5131   }
5132   target_friend->congestion_timestamp =
5133           GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(),
5134                                     congestion_timeout);
5135
5136   /* I am the source peer which wants to setup the trail. Do nothing.
5137    * send_find_finger_trail_task is scheduled periodically.*/
5138   if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &source)))
5139     return GNUNET_OK;
5140
5141   /* If I am congested then pass this message to peer before me in trail. */
5142   if(GNUNET_YES == GDS_ROUTING_threshold_reached())
5143   {
5144     if (0 == trail_length)
5145       next_peer = source;
5146     else
5147       next_peer = trail_peer_list[trail_length-1];
5148
5149     target_friend =
5150                    GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_peer);
5151     if (NULL == target_friend)
5152     {
5153       DEBUG ("\nLINE = %d ,No friend found.",__LINE__);
5154       GNUNET_break(0);
5155       return GNUNET_OK;
5156     }
5157     GDS_NEIGHBOURS_send_trail_rejection (source,
5158                                          ultimate_destination_finger_value,
5159                                          my_identity, is_predecessor,
5160                                          trail_peer_list,trail_length,trail_id,
5161                                          target_friend, CONGESTION_TIMEOUT);
5162     return GNUNET_OK;
5163   }
5164
5165   struct Closest_Peer successor;
5166   successor = find_successor (ultimate_destination_finger_value, is_predecessor);
5167
5168   /* Am I the final destination? */
5169   if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&successor.best_known_destination,
5170                                              &my_identity)))
5171   {
5172     if (0 == trail_length)
5173       next_peer = source;
5174     else
5175       next_peer = trail_peer_list[trail_length-1];
5176     
5177     target_friend =
5178                    GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_peer);
5179     if (NULL == target_friend)
5180     {
5181       DEBUG ("\nLINE = %d ,No friend found.",__LINE__);
5182       GNUNET_break(0);
5183       return GNUNET_OK;
5184     }
5185     GDS_NEIGHBOURS_send_trail_setup_result (source,
5186                                             my_identity,
5187                                             target_friend, trail_length,
5188                                             trail_peer_list,
5189                                             is_predecessor,
5190                                             ultimate_destination_finger_value,
5191                                             trail_id);
5192   }
5193   else
5194   {
5195     struct GNUNET_PeerIdentity peer_list[trail_length + 1];
5196
5197     memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
5198     peer_list[trail_length] = my_identity;
5199
5200     target_friend =
5201                    GNUNET_CONTAINER_multipeermap_get (friend_peermap, 
5202                                                       &successor.next_hop);
5203     if (NULL == target_friend)
5204     {
5205       DEBUG ("\nLINE = %d ,No friend found.",__LINE__);
5206       GNUNET_break(0);
5207       return GNUNET_OK;
5208     }
5209     GDS_NEIGHBOURS_send_trail_setup (source,
5210                                      ultimate_destination_finger_value,
5211                                      successor.best_known_destination,
5212                                      target_friend, trail_length + 1, peer_list,
5213                                      is_predecessor, trail_id,
5214                                      successor.trail_id);
5215   }
5216   return GNUNET_OK;
5217 }
5218
5219
5220 /**
5221  * Core handler for trail teardown message.
5222  * @param cls closure
5223  * @param message message
5224  * @param peer sender of this messsage.
5225  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
5226  */
5227 static int
5228 handle_dht_p2p_trail_teardown (void *cls, const struct GNUNET_PeerIdentity *peer,
5229                                const struct GNUNET_MessageHeader *message)
5230 {
5231   const struct PeerTrailTearDownMessage *trail_teardown;
5232   enum GDS_ROUTING_trail_direction trail_direction;
5233   struct GNUNET_HashCode trail_id;
5234   struct GNUNET_PeerIdentity *next_hop;
5235   size_t msize;
5236
5237   msize = ntohs (message->size);
5238
5239   /* Here we pass only the trail id. */
5240   if (msize != sizeof (struct PeerTrailTearDownMessage))
5241   {
5242     GNUNET_break_op (0);
5243     return GNUNET_OK;
5244   }
5245
5246   GNUNET_STATISTICS_update (GDS_stats,
5247                             gettext_noop
5248                             ("# Bytes received from other peers"), msize,
5249                             GNUNET_NO);
5250   
5251   trail_teardown = (const struct PeerTrailTearDownMessage *) message;
5252   trail_direction = ntohl (trail_teardown->trail_direction);
5253   trail_id = trail_teardown->trail_id;
5254
5255   /* Check if peer is the real peer from which we should get this message.*/
5256   /* Get the prev_hop for this trail by getting the next hop in opposite direction. */
5257 #if 0
5258   GNUNET_assert (NULL != (prev_hop =
5259                  GDS_ROUTING_get_next_hop (trail_id, !trail_direction)));
5260   if (0 != GNUNET_CRYPTO_cmp_peer_identity (prev_hop, peer))
5261   {
5262     GNUNET_break (0);
5263     return GNUNET_SYSERR;
5264   }
5265 #endif
5266
5267   next_hop = GDS_ROUTING_get_next_hop (trail_id, trail_direction);
5268   if (NULL == next_hop)
5269   {
5270     DEBUG(" NO ENTRY FOUND IN %s ROUTING TABLE for trail id %s, line",
5271             GNUNET_i2s(&my_identity), GNUNET_h2s(&trail_id), __LINE__);
5272     GNUNET_break (0);
5273     return GNUNET_SYSERR;
5274   }
5275
5276   /* I am the next hop, which means I am the final destination. */
5277   if (0 == GNUNET_CRYPTO_cmp_peer_identity (next_hop, &my_identity))
5278   {
5279     GNUNET_assert (GNUNET_YES == GDS_ROUTING_remove_trail (trail_id));
5280     return GNUNET_OK;
5281   }
5282   else
5283   {
5284     /* If not final destination, then send a trail teardown message to next hop.*/
5285     GNUNET_assert (NULL != GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop));
5286     GNUNET_assert (GNUNET_YES == GDS_ROUTING_remove_trail (trail_id));
5287     GDS_NEIGHBOURS_send_trail_teardown (trail_id, trail_direction, *next_hop);
5288   }
5289
5290   return GNUNET_OK;
5291 }
5292
5293
5294 /**
5295  * Core handle for p2p add trail message.
5296  * @param cls closure
5297  * @param message message
5298  * @param peer peer identity this notification is about
5299  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
5300  */
5301 static int
5302 handle_dht_p2p_add_trail (void *cls, const struct GNUNET_PeerIdentity *peer,
5303                           const struct GNUNET_MessageHeader *message)
5304 {
5305   const struct PeerAddTrailMessage *add_trail;
5306   const struct GNUNET_PeerIdentity *trail;
5307   struct GNUNET_HashCode trail_id;
5308   struct GNUNET_PeerIdentity destination_peer;
5309   struct GNUNET_PeerIdentity source_peer;
5310   struct GNUNET_PeerIdentity next_hop;
5311   unsigned int trail_length;
5312   unsigned int my_index;
5313   size_t msize;
5314
5315   msize = ntohs (message->size);
5316   /* In this message we pass the whole trail from source to destination as we
5317    * are adding that trail.*/
5318   //FIXME: failed when run with 1000 pears. check why.
5319   if (msize < sizeof (struct PeerAddTrailMessage))
5320   {
5321     GNUNET_break_op (0);
5322     return GNUNET_OK;
5323   }
5324
5325   add_trail = (const struct PeerAddTrailMessage *) message;
5326   trail_length = (msize - sizeof (struct PeerAddTrailMessage))/
5327                   sizeof (struct GNUNET_PeerIdentity);
5328   if ((msize - sizeof (struct PeerAddTrailMessage)) %
5329       sizeof (struct GNUNET_PeerIdentity) != 0)
5330   {
5331     GNUNET_break_op (0);
5332     return GNUNET_OK;
5333   }
5334
5335   GNUNET_STATISTICS_update (GDS_stats,
5336                             gettext_noop
5337                             ("# Bytes received from other peers"), msize,
5338                             GNUNET_NO);
5339   
5340   trail = (const struct GNUNET_PeerIdentity *)&add_trail[1];
5341   destination_peer = add_trail->destination_peer;
5342   source_peer = add_trail->source_peer;
5343   trail_id = add_trail->trail_id;
5344
5345   //FIXME: add a check that sender peer is not malicious. Make it a generic
5346   // function so that it can be used in all other functions where we need the
5347   // same functionality.
5348
5349   /* I am not the destination of the trail. */
5350   if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &destination_peer))
5351   {
5352     struct FriendInfo *target_friend;
5353
5354     /* Get my location in the trail. */
5355     my_index = search_my_index (trail, trail_length);
5356     if (-1 == my_index)
5357     {
5358       GNUNET_break_op (0);
5359       return GNUNET_SYSERR;
5360     }
5361     if((trail_length + 1) == my_index)
5362     {
5363       DEBUG ("Found twice in trail.\n");
5364       GNUNET_break_op (0);
5365       return GNUNET_SYSERR;
5366     }
5367     if ((trail_length - 1) == my_index)
5368     {
5369       next_hop = destination_peer;
5370     }
5371     else
5372     {
5373       next_hop = trail[my_index + 1];
5374     }
5375     /* Add in your routing table. */
5376     GNUNET_assert (GNUNET_OK == GDS_ROUTING_add (trail_id, next_hop, *peer));
5377     GNUNET_assert (NULL !=
5378                   (target_friend =
5379                    GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop)));
5380     GDS_NEIGHBOURS_send_add_trail (source_peer, destination_peer, trail_id,
5381                                    trail, trail_length, target_friend);
5382     return GNUNET_OK;
5383   }
5384   /* I am the destination. Add an entry in routing table. */
5385   GNUNET_assert (GNUNET_OK == GDS_ROUTING_add (trail_id, *peer, my_identity));
5386   return GNUNET_OK;
5387 }
5388
5389
5390 /**
5391  * Free the finger trail in which the first friend to reach to a finger is
5392  * disconnected_friend. Also remove entry from routing table for that particular
5393  * trail id.
5394  * @param disconnected_friend PeerIdentity of friend which got disconnected
5395  * @param remove_finger Finger whose trail we need to check if it has
5396  *                      disconnected_friend as the first hop.
5397  * @return Total number of trails in which disconnected_friend was the first
5398  *         hop.
5399  */
5400 static int
5401 remove_matching_trails (const struct GNUNET_PeerIdentity *disconnected_friend,
5402                         struct FingerInfo *finger)
5403 {
5404   unsigned int matching_trails_count = 0;
5405   int i;
5406
5407   /* Iterate over all the trails of finger. */
5408   for (i = 0; i < finger->trails_count; i++)
5409   {
5410     struct Trail *current_trail;
5411     current_trail = &finger->trail_list[i];
5412     //FIXME: This assertion fails if we have gap in trail list from o to trails count.
5413     GNUNET_assert (GNUNET_YES == current_trail->is_present);
5414     /* First friend to reach to finger is disconnected_peer. */
5415     if (0 == GNUNET_CRYPTO_cmp_peer_identity (&current_trail->trail_head->peer,
5416                                               disconnected_friend))
5417     {
5418       struct GNUNET_PeerIdentity *next_hop;
5419       struct FriendInfo *remove_friend;
5420
5421       GNUNET_assert (NULL !=
5422                     (remove_friend =
5423                      GNUNET_CONTAINER_multipeermap_get (friend_peermap,
5424                                                         disconnected_friend)));
5425       next_hop = GDS_ROUTING_get_next_hop (current_trail->trail_id,
5426                                            GDS_ROUTING_SRC_TO_DEST);
5427
5428       /* Here it may happen that as all the peers got disconnected, the entry in
5429        routing table for that particular trail has been removed, because the
5430        previously disconnected peer was either a next hop or prev hop of that
5431        peer. */
5432       if (NULL != next_hop)
5433       {
5434         GNUNET_assert (0 == (GNUNET_CRYPTO_cmp_peer_identity (disconnected_friend,
5435                                                             next_hop)));
5436         GNUNET_assert (GNUNET_YES == GDS_ROUTING_remove_trail (current_trail->trail_id));
5437       }
5438       matching_trails_count++;
5439       free_trail (current_trail);
5440       current_trail->is_present = GNUNET_NO;
5441     }
5442   }
5443   return matching_trails_count;
5444 }
5445
5446
5447 /**
5448  * Iterate over finger_table entries.
5449  * 0. Ignore finger which is my_identity or if no valid entry present at
5450  *    that finger index.
5451  * 1. If disconnected_friend is a finger, then remove the routing entry from
5452       your own table. Free the trail.
5453  * 2. Check if disconnected_friend is the first friend in the trail to reach to a finger.
5454  *   2.1 Remove all the trails and entry from routing table in which disconnected
5455  *       friend is the first friend in the trail. If disconnected_friend is the
5456  *       first friend in all the trails to reach finger, then remove the finger.
5457  * @param disconnected_friend Peer identity of friend which got disconnected.
5458  */
5459 static void
5460 remove_matching_fingers (const struct GNUNET_PeerIdentity *disconnected_peer)
5461 {
5462   struct FingerInfo *current_finger;
5463   struct FriendInfo *remove_friend;
5464   int removed_trails_count;
5465   int i;
5466
5467   /* Iterate over finger table entries. */
5468   for (i = 0; i < MAX_FINGERS; i++)
5469   {
5470     current_finger = &finger_table[i];
5471     
5472     /* No finger stored at this trail index. */
5473     if ((GNUNET_NO == current_finger->is_present) ||
5474         (0 == GNUNET_CRYPTO_cmp_peer_identity (&current_finger->finger_identity,
5475                                               &my_identity)))
5476       continue;
5477     
5478     /* Is disconnected_peer a finger? */
5479     if (0 == GNUNET_CRYPTO_cmp_peer_identity (disconnected_peer,
5480                                               &current_finger->finger_identity))
5481     {
5482       struct GNUNET_PeerIdentity *next_hop;
5483       struct GNUNET_HashCode trail_id;
5484       
5485       GNUNET_assert (0 == current_finger->trail_list[0].trail_length);
5486       GNUNET_assert (GNUNET_YES == (current_finger->trail_list[0].is_present));
5487       trail_id = current_finger->trail_list[0].trail_id;
5488  
5489       if(NULL !=
5490               (next_hop =
5491                GDS_ROUTING_get_next_hop (trail_id, GDS_ROUTING_SRC_TO_DEST)))
5492       {
5493         GNUNET_assert (GNUNET_YES == GDS_ROUTING_remove_trail (trail_id));
5494         GNUNET_assert (NULL !=
5495                        (remove_friend =
5496                         GNUNET_CONTAINER_multipeermap_get (friend_peermap,
5497                                                            disconnected_peer)));
5498       }
5499       current_finger->trail_list[0].is_present = GNUNET_NO;
5500       current_finger->is_present = GNUNET_NO;
5501       memset ((void *)&finger_table[i], 0, sizeof (finger_table[i]));
5502       continue;
5503     }
5504
5505     /* If finger is a friend but not disconnected_friend, then continue. */
5506     if (NULL != GNUNET_CONTAINER_multipeermap_get (friend_peermap,
5507                                                    &current_finger->finger_identity))
5508       continue;
5509
5510     /* Iterate over the list of trails to reach remove_finger. Check if
5511      * disconnected_friend is the first friend in any of the trail. */
5512     removed_trails_count = remove_matching_trails (disconnected_peer,
5513                                                    current_finger);
5514     current_finger->trails_count =
5515             current_finger->trails_count - removed_trails_count;
5516     if (0 == current_finger->trails_count)
5517     {
5518       current_finger->is_present = GNUNET_NO;
5519       memset ((void *)&finger_table[i], 0, sizeof (finger_table[i]));
5520     }
5521   }
5522 }
5523
5524
5525 /**
5526  * Method called whenever a peer disconnects.
5527  *
5528  * @param cls closure
5529  * @param peer peer identity this notification is about
5530  */
5531 static void
5532 handle_core_disconnect (void *cls,
5533                                           const struct GNUNET_PeerIdentity *peer)
5534 {
5535   struct FriendInfo *remove_friend;
5536   struct P2PPendingMessage *pos;
5537   unsigned int discarded;
5538   
5539   /* If disconnected to own identity, then return. */
5540   if (0 == memcmp (&my_identity, peer, sizeof (struct GNUNET_PeerIdentity)))
5541     return;
5542
5543   if(NULL == (remove_friend =
5544                  GNUNET_CONTAINER_multipeermap_get (friend_peermap, peer)))
5545   {
5546     DEBUG("\n friend already disconnected.");
5547     return;
5548   }
5549   
5550   remove_matching_fingers (peer);
5551   GNUNET_assert (GNUNET_SYSERR != GDS_ROUTING_remove_trail_by_peer (peer));
5552   GNUNET_assert (GNUNET_YES ==
5553                  GNUNET_CONTAINER_multipeermap_remove (friend_peermap,
5554                                                        peer,
5555                                                        remove_friend));
5556   
5557   /* Remove all the messages queued in pending list of this peer is discarded.*/
5558   if (remove_friend->th != NULL)
5559   {
5560     GNUNET_CORE_notify_transmit_ready_cancel(remove_friend->th);
5561     remove_friend->th = NULL;
5562   }
5563   
5564   discarded = 0;
5565   while (NULL != (pos = remove_friend->head))
5566   {
5567     GNUNET_CONTAINER_DLL_remove (remove_friend->head, remove_friend->tail, pos);
5568     discarded++;
5569     GNUNET_free (pos);
5570   }
5571   
5572   GNUNET_STATISTICS_update (GDS_stats,
5573                             gettext_noop
5574                             ("# Queued messages discarded (peer disconnected)"),
5575                             discarded, GNUNET_NO);
5576   //GNUNET_free (remove_friend);
5577   
5578   if (0 != GNUNET_CONTAINER_multipeermap_size (friend_peermap))
5579     return;
5580
5581   if (GNUNET_SCHEDULER_NO_TASK != find_finger_trail_task)
5582   {
5583       GNUNET_SCHEDULER_cancel (find_finger_trail_task);
5584       find_finger_trail_task = GNUNET_SCHEDULER_NO_TASK;
5585   }
5586   else
5587     GNUNET_break (0);
5588 }
5589
5590
5591 /**
5592  * Method called whenever a peer connects.
5593  *
5594  * @param cls closure
5595  * @param peer_identity peer identity this notification is about
5596  */
5597 static void
5598 handle_core_connect (void *cls, const struct GNUNET_PeerIdentity *peer_identity)
5599 {
5600   struct FriendInfo *friend;
5601
5602   /* Check for connect to self message */
5603   if (0 == memcmp (&my_identity, peer_identity, sizeof (struct GNUNET_PeerIdentity)))
5604     return;
5605
5606   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected to %s\n", GNUNET_i2s (peer_identity));
5607
5608   /* If peer already exists in our friend_peermap, then exit. */
5609   if (GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains (friend_peermap,
5610                                                             peer_identity))
5611   {
5612     GNUNET_break (0);
5613     return;
5614   }
5615
5616   friend = GNUNET_new (struct FriendInfo);
5617   friend->id = *peer_identity;
5618
5619   GNUNET_assert (GNUNET_OK ==
5620                  GNUNET_CONTAINER_multipeermap_put (friend_peermap,
5621                                                     peer_identity, friend,
5622                                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
5623
5624   /* got a first connection, good time to start with FIND FINGER TRAIL requests...*/
5625   if (GNUNET_SCHEDULER_NO_TASK == find_finger_trail_task)
5626   {
5627     find_finger_trail_task = GNUNET_SCHEDULER_add_now (&send_find_finger_trail_message, NULL);
5628   }
5629 }
5630
5631
5632 /**
5633  * To be called on core init/fail.
5634  *
5635  * @param cls service closure
5636  * @param identity the public identity of this peer
5637  */
5638 static void
5639 core_init (void *cls,
5640            const struct GNUNET_PeerIdentity *identity)
5641 {
5642   my_identity = *identity;
5643
5644   uint64_t my_id64;
5645   memcpy (&my_id64, &my_identity, sizeof (uint64_t));
5646   my_id64 = GNUNET_ntohll (my_id64);
5647   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5648               "my_indentity = %s, my_id64=%llu\n",GNUNET_i2s(&my_identity),(unsigned long long)my_id64);
5649
5650 }
5651
5652
5653 /**
5654  * Initialize finger table entries.
5655  */
5656 static void
5657 finger_table_init ()
5658 {
5659   memset (&finger_table, 0, sizeof (finger_table));
5660 }
5661
5662
5663 /**
5664  * Initialize neighbours subsystem.
5665  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
5666  */
5667 int
5668 GDS_NEIGHBOURS_init (void)
5669 {
5670   static struct GNUNET_CORE_MessageHandler core_handlers[] = {
5671     {&handle_dht_p2p_put, GNUNET_MESSAGE_TYPE_XDHT_P2P_PUT, 0},
5672     {&handle_dht_p2p_get, GNUNET_MESSAGE_TYPE_XDHT_P2P_GET, 0},
5673     {&handle_dht_p2p_get_result, GNUNET_MESSAGE_TYPE_XDHT_P2P_GET_RESULT, 0},
5674     {&handle_dht_p2p_trail_setup, GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_SETUP, 0},
5675     {&handle_dht_p2p_trail_setup_result, GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_SETUP_RESULT, 0},
5676     {&handle_dht_p2p_verify_successor, GNUNET_MESSAGE_TYPE_XDHT_P2P_VERIFY_SUCCESSOR, 0},
5677     {&handle_dht_p2p_verify_successor_result, GNUNET_MESSAGE_TYPE_XDHT_P2P_VERIFY_SUCCESSOR_RESULT, 0},
5678     {&handle_dht_p2p_notify_new_successor, GNUNET_MESSAGE_TYPE_XDHT_P2P_NOTIFY_NEW_SUCCESSOR, 0},
5679     {&handle_dht_p2p_trail_setup_rejection, GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_SETUP_REJECTION, 0},
5680     {&handle_dht_p2p_trail_teardown, GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_TEARDOWN,
5681                                      sizeof (struct PeerTrailTearDownMessage)},
5682     {&handle_dht_p2p_add_trail, GNUNET_MESSAGE_TYPE_XDHT_P2P_ADD_TRAIL, 0},
5683     {NULL, 0, 0}
5684   };
5685   
5686 #if ENABLE_MALICIOUS
5687   act_malicious = 0;
5688 #endif
5689   
5690   core_api =
5691     GNUNET_CORE_connect (GDS_cfg, NULL, &core_init, &handle_core_connect,
5692                          &handle_core_disconnect, NULL, GNUNET_NO, NULL,
5693                          GNUNET_NO, core_handlers);
5694   
5695   if (NULL == core_api)
5696     return GNUNET_SYSERR;
5697
5698   //TODO: check size of this peer map? 
5699   friend_peermap = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_NO);
5700   finger_table_init ();
5701   
5702   find_finger_trail_task_next_send_time.rel_value_us =
5703       DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us +
5704       GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
5705                                 DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us);
5706   
5707   verify_successor_next_send_time.rel_value_us = 
5708       DHT_SEND_VERIFY_SUCCESSOR_INTERVAL.rel_value_us +
5709       GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
5710                                 DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us);
5711   
5712   return GNUNET_OK;
5713 }
5714
5715 /**
5716  * Free the memory held up by trails of a finger. 
5717  */
5718 static void
5719 delete_finger_table_entries()
5720 {
5721   unsigned int i;
5722   unsigned int j;
5723   
5724   for(i = 0; i < MAX_FINGERS; i++)
5725   {
5726     if(GNUNET_NO == finger_table[i].is_present)
5727       continue;
5728     
5729     for(j = 0; j < finger_table[i].trails_count; j++)
5730     {
5731       free_trail(&finger_table[i].trail_list[i]);
5732     }
5733   }
5734 }
5735
5736 /**
5737  * Shutdown neighbours subsystem.
5738  */
5739 void
5740 GDS_NEIGHBOURS_done (void)
5741 {
5742   if (NULL == core_api)
5743     return;
5744
5745   GNUNET_CORE_disconnect (core_api);
5746   core_api = NULL;
5747
5748   delete_finger_table_entries();
5749   
5750   GNUNET_assert (0 == GNUNET_CONTAINER_multipeermap_size (friend_peermap));
5751   GNUNET_CONTAINER_multipeermap_destroy (friend_peermap);
5752   friend_peermap = NULL;
5753
5754   if (GNUNET_SCHEDULER_NO_TASK != find_finger_trail_task)
5755   {
5756     GNUNET_break (0);
5757     GNUNET_SCHEDULER_cancel (find_finger_trail_task);
5758     find_finger_trail_task = GNUNET_SCHEDULER_NO_TASK;
5759   }
5760
5761   if (GNUNET_SCHEDULER_NO_TASK != send_verify_successor_task)
5762   {
5763     GNUNET_SCHEDULER_cancel (send_verify_successor_task);
5764     send_verify_successor_task = GNUNET_SCHEDULER_NO_TASK;
5765   }
5766 }
5767
5768
5769 /**
5770  * Get my identity
5771  *
5772  * @return my identity
5773  */
5774 struct GNUNET_PeerIdentity
5775 GDS_NEIGHBOURS_get_my_id (void)
5776 {
5777   return my_identity;
5778 }
5779
5780 /* end of gnunet-service-xdht_neighbours.c */