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