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