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