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