remove protocol violation
[oweals/gnunet.git] / src / dht / gnunet-service-xdht_neighbours.c
1 /*
2      This file is part of GNUnet.
3      (C) 2009-2014 Christian Grothoff (and other contributing authors)
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21 /**
22  * @file dht/gnunet-service-xdht_neighbours.c
23  * @brief GNUnet DHT service's finger and friend table management code
24  * @author Supriti Singh
25  */
26
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
29 #include "gnunet_block_lib.h"
30 #include "gnunet_hello_lib.h"
31 #include "gnunet_constants.h"
32 #include "gnunet_protocols.h"
33 #include "gnunet_ats_service.h"
34 #include "gnunet_core_service.h"
35 #include "gnunet_datacache_lib.h"
36 #include "gnunet_transport_service.h"
37 #include "gnunet_dht_service.h"
38 #include "gnunet_statistics_service.h"
39 #include "gnunet-service-xdht.h"
40 #include "gnunet-service-xdht_clients.h"
41 #include "gnunet-service-xdht_datacache.h"
42 #include "gnunet-service-xdht_neighbours.h"
43 #include "gnunet-service-xdht_routing.h"
44 #include <fenv.h>
45 #include "dht.h"
46
47 /**
48  * Maximum possible fingers of a peer.
49  */
50 #define MAX_FINGERS 65
51
52 /**
53  * Maximum allowed number of pending messages per friend peer.
54  */
55 #define MAXIMUM_PENDING_PER_FRIEND 64
56
57 /**
58  * How long to wait before sending another find finger trail request
59  */
60 #define DHT_FIND_FINGER_TRAIL_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
61
62 /**
63  * How long at most to wait for transmission of a request to another peer?
64  */
65 #define GET_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 2)
66
67 /**
68  * How long will I remain congested?
69  */
70 #define CONGESTION_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 2)
71
72 /**
73  * Maximum number of trails stored per finger.
74  */
75 #define MAXIMUM_TRAILS_PER_FINGER 2
76
77 /**
78  * Used to distinguish put/get request use of find_successor() from others
79  */
80 #define PUT_GET_REQUEST 65
81
82 /**
83  * Maximum number of trails that can go through a friend.
84  */
85 #define TRAIL_THROUGH_FRIEND_THRESHOLD 64
86
87 /**
88  * Finger map index for predecessor entry in finger peermap.
89  */
90 #define PREDECESSOR_FINGER_ID 64
91
92 /**
93  * Maximum number of trails allowed to go through a friend.
94  */
95 #define TRAILS_THROUGH_FRIEND_THRESHOLD 64
96
97 /**
98  * Wrap around in peer identity circle. 
99  */
100 #define PEER_IDENTITES_WRAP_AROUND pow(2, 256) - 1
101
102 GNUNET_NETWORK_STRUCT_BEGIN
103
104 /**
105  * P2P Trail setup message
106  */
107 struct PeerTrailSetupMessage
108 {
109   /**
110    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP
111    */
112   struct GNUNET_MessageHeader header;
113
114   /* Bitmask of options, 1 = IS_PREDECESSOR */
115   // int32_t options;
116
117   /**
118    * Peer closest to this value will be our finger.
119    */
120   uint64_t ultimate_destination_finger;
121
122   /**
123    * Source peer which wants to setup the trail to one of its finger.
124    */
125   struct GNUNET_PeerIdentity source_peer;
126
127   /**
128    * Peer to which this packet is forwarded.
129    */
130   struct GNUNET_PeerIdentity next_destination; // rename "best_known_dest"
131
132   /**
133    * Index into finger peer map, in Network Byte Order.
134    */
135   uint32_t finger_map_index; // remove this, include ultimate_destination_finger in response, calculate index from it
136
137   /**
138    * Number of entries in trail_list, in Network Byte Order.
139    */
140   uint32_t trail_length GNUNET_PACKED; // remove this, calculte length from message size
141
142   /**
143    * Trail id of any intermediate trail we may encounter while doing trail setup.
144    */
145   struct GNUNET_HashCode intermediate_trail_id;
146
147   /**
148    * Trail id for trail which we are trying to setup.
149    */
150   struct GNUNET_HashCode new_trail_id; // rename to "trail_id"
151
152   /* Trail formed in the process. */
153   /* GNUNET_PeerIdentity trail_list[] */
154 };
155
156 /**
157   * P2P Trail Setup Result message
158  */
159 struct PeerTrailSetupResultMessage
160 {
161
162   /**
163    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP_RESULT
164    */
165   struct GNUNET_MessageHeader header;
166
167   /**
168    * Finger to which we have found the path.
169    */
170   struct GNUNET_PeerIdentity finger_identity;
171
172   /**
173    * Peer which was looking for the trail to finger.
174    */
175   struct GNUNET_PeerIdentity destination_peer; // querying_peer
176
177   /**
178    * Index into finger peer map in NBO.
179    */
180   uint32_t finger_map_index; // flag/option with IS_PREDECESSOR
181
182   /**
183    * Number of entries in trail list in NBO.
184    */
185   uint32_t trail_length GNUNET_PACKED; // remove, calculate
186
187   /**
188    * Identifier of the trail.
189    */
190   struct GNUNET_HashCode trail_id;
191
192   /* Trail from "destination_peer" to finger_identity, NOT including both */
193   /* struct GNUNET_PeerIdentity trail[] */
194 };
195
196 /**
197  * P2P Verify Successor Message.
198  */
199 struct PeerVerifySuccessorMessage
200 {
201   /**
202    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR
203    */
204   struct GNUNET_MessageHeader header;
205
206   /**
207    * Source peer which wants to verify its successor.
208    */
209   struct GNUNET_PeerIdentity source_peer;
210
211   /**
212    * My current successor.
213    */
214   struct GNUNET_PeerIdentity successor;
215
216   /**
217    * Identifier of trail to reach from source_peer to successor.
218    */
219   struct GNUNET_HashCode trail_id;
220
221   /**
222    * Total number of peers to reach from source to successor.
223    */
224   unsigned int trail_length;
225
226   /* Trail. */
227 };
228
229 /**
230  * P2P Verify Successor Result Message
231  */
232 struct PeerVerifySuccessorResultMessage
233 {
234   /**
235    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR_RESULT
236    */
237   struct GNUNET_MessageHeader header;
238
239   /**
240    * Destination peer which sent the request to verify its successor.
241    */
242   struct GNUNET_PeerIdentity destination_peer;
243
244   /**
245    * Successor to which PeerVerifySuccessorMessage was sent.
246    */
247   struct GNUNET_PeerIdentity source_successor;
248
249   /**
250    * source_successor's predecessor
251    */
252   struct GNUNET_PeerIdentity my_predecessor;
253
254   /**
255    * Trail identifier of trail from my_predecessor to source_successor.
256    */
257   struct GNUNET_HashCode trail_id;
258
259   /**
260    * Direction in which we are looking at the trail.
261    */
262   enum GDS_ROUTING_trail_direction trail_direction;
263
264   /**
265    * Total number of peers in trail from source_successor to my_predecessor
266    * if my_predecessor is not same as destination_peer.
267    */
268   uint32_t trail_length;
269
270   /* Trail from source_successor to my_predecessor where
271    * my_predecessor != destination_peer*/
272 };
273
274 /**
275  * P2P Notify New Successor Message.
276  */
277 struct PeerNotifyNewSuccessorMessage
278 {
279   /**
280    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_NEW_SUCCESSOR
281    */
282   struct GNUNET_MessageHeader header;
283
284   /**
285    * Source peer which wants to notify its new successor.
286    */
287   struct GNUNET_PeerIdentity source_peer;
288
289   /**
290    * New successor identity.
291    */
292   struct GNUNET_PeerIdentity destination_peer;
293
294   /**
295    * Total number of peers in trail from source_peer to destination_peer
296    */
297   unsigned int trail_length;
298
299   /**
300    * Unique identifier of the trail.
301    */
302   struct GNUNET_HashCode trail_id;
303
304   /* Trail. */
305 };
306
307 /**
308  * P2P Trail Compression Message.
309  */
310 struct PeerTrailCompressionMessage
311 {
312   /**
313    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_COMPRESSION
314    */
315   struct GNUNET_MessageHeader header;
316
317   /**
318    * Source peer of this trail.
319    */
320   struct GNUNET_PeerIdentity source_peer;
321
322   /**
323    * Destination of this trail.
324    */
325   struct GNUNET_PeerIdentity destination_peer;
326
327   /**
328    * Trail from source_peer to destination_peer compressed such that
329    * new_first_friend is the first hop in the trail from source to
330    * destination.
331    */
332   struct GNUNET_PeerIdentity new_first_friend;
333
334   /**
335    * Unique identifier of trail.
336    */
337   struct GNUNET_HashCode trail_id;
338 };
339
340
341 /**
342  * P2P Trail Tear Down message.
343  */
344 struct PeerTrailTearDownMessage
345 {
346   /**
347    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_TEARDOWN
348    */
349   struct GNUNET_MessageHeader header;
350
351   /**
352    * Source peer of the trail.
353    */
354   struct GNUNET_PeerIdentity source_peer;
355
356   /**
357    * Destination peer of the trail.
358    */
359   struct GNUNET_PeerIdentity destination_peer;
360
361   /**
362    * Unique identifier of the trail.
363    */
364   struct GNUNET_HashCode TRAIL_ID;
365
366   /**
367    * Direction of trail.
368    */
369   enum GDS_ROUTING_trail_direction trail_direction;
370 };
371
372
373 /**
374  * P2P Trail Rejection Message.
375  */
376 struct PeerTrailRejectionMessage
377 {
378   /**
379    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_REJECTION
380    */
381   struct GNUNET_MessageHeader header;
382
383   /**
384    * Source peer which wants to set up the trail.
385    */
386   struct GNUNET_PeerIdentity source_peer;
387
388   /**
389    * Peer which sent trail rejection message.
390    */
391   struct GNUNET_PeerIdentity congested_peer;
392
393   /**
394    * Peer identity which will be successor to this value will be finger of
395    * source_peer.
396    */
397   uint64_t ultimate_destination_finger_identity_value;
398
399   /**
400    * Index in finger peer map of source peer.
401    */
402   uint32_t finger_map_index;
403
404   /**
405    * Total number of peers in the trail.
406    */
407   uint32_t trail_length;
408
409   /**
410    * Identifier for the trail source peer is trying to setup.
411    */
412   struct GNUNET_HashCode trail_id;
413   /**
414    * Relative time for which congested_peer will remain congested.
415    */
416   struct GNUNET_TIME_Relative congestion_time;
417
418   /* Trail_list from source_peer to peer which sent the message for trail setup
419    * to congested peer.*/
420 };
421
422 /**
423  * P2P Add Trail Message.
424  */
425 struct PeerAddTrailMessage
426 {
427   /**
428    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_ADD_TRAIL
429    */
430   struct GNUNET_MessageHeader header;
431
432   /**
433    * Source peer of the routing trail.
434    */
435   struct GNUNET_PeerIdentity source_peer;
436
437   /**
438    * Destination peer of the routing trail.
439    */
440   struct GNUNET_PeerIdentity destination_peer;
441
442   /**
443    * Total number of peers from source peer to destination peer.
444    */
445   unsigned int trail_length;
446
447   /**
448    * Unique identifier of the trail.
449    */
450   struct GNUNET_HashCode trail_id;
451
452   /* Trail from source peer to destination peer. */
453 };
454
455 GNUNET_NETWORK_STRUCT_END
456
457 /**
458  * Linked list of messages to send to a particular other peer.
459  */
460 struct P2PPendingMessage
461 {
462   /**
463    * Pointer to next item in the list
464    */
465   struct P2PPendingMessage *next;
466
467   /**
468    * Pointer to previous item in the list
469    */
470   struct P2PPendingMessage *prev;
471
472   /**
473    * Message importance level.  FIXME: used? useful?
474    */
475   unsigned int importance;
476
477   /**
478    * When does this message time out?
479    */
480   struct GNUNET_TIME_Absolute timeout;
481
482   /**
483    * Actual message to be sent, allocated at the end of the struct:
484    * // msg = (cast) &pm[1];
485    * // memcpy (&pm[1], data, len);
486    */
487   const struct GNUNET_MessageHeader *msg;
488
489 };
490
491
492 /**
493  *  Entry in friend_peermap.
494  */
495 struct FriendInfo
496 {
497   /**
498    * Friend Identity
499    */
500   struct GNUNET_PeerIdentity id;
501
502   /**
503    * Number of trails for which this friend is the first hop.
504    */
505   unsigned int trails_count;
506
507   /**
508    * Count of outstanding messages for this friend.
509    */
510   unsigned int pending_count;
511
512   /**
513    * In case not 0, then amount of time for which this friend is congested.
514    */
515   struct GNUNET_TIME_Absolute congestion_timestamp;
516
517   /**
518    * Head of pending messages to be sent to this friend.
519    */
520   struct P2PPendingMessage *head;
521
522   /**
523    * Tail of pending messages to be sent to this friend.
524    */
525   struct P2PPendingMessage *tail;
526
527   /**
528    * Core handle for sending messages to this friend.
529    */
530   struct GNUNET_CORE_TransmitHandle *th;
531
532 };
533
534 /**
535  * An individual trail to reach to a finger.
536  */
537 struct Trail // "node" "element" "relay"
538 {
539   /**
540     * Pointer to next item in the list
541     */
542   struct Trail *next;
543
544   /**
545     * Pointer to prev item in the list
546     */
547   struct Trail *prev;
548
549   /**
550    * An element in this trail.
551    */
552   struct GNUNET_PeerIdentity peer;
553 };
554
555 /**
556  * List of all trails to reach a particular finger.
557  */
558 struct TrailList // "trail": list of "elements"
559 {
560   /**
561    * Head of trail.
562    */
563   struct Trail *trail_head;
564
565   /**
566    * Tail of trail.
567    */
568   struct Trail *trail_tail;
569
570   /**
571    * Unique identifier of this trail.
572    */
573   struct GNUNET_HashCode trail_id;
574
575   /**
576    * Length of trail pointed
577    */
578   unsigned int trail_length;
579
580   /**
581    * Number of trails that the first friend of this trail is a part of.
582    */
583   unsigned int first_friend_trail_count; // remove this, duplicate variable!
584                                          // include a pointer to Friend or function that calculates it
585 };
586
587 /**
588  * An entry in finger_hashmap.
589  */
590 struct FingerInfo
591 {
592   /**
593    * Finger identity.
594    */
595   struct GNUNET_PeerIdentity finger_identity;
596
597   /**
598    * Index in finger peer map
599    */
600   uint32_t finger_map_index;
601
602   /**
603    * Number of trails setup so far for this finger.
604    */
605   uint32_t trails_count;
606
607   /**
608    * Array of trails.
609    */
610   struct TrailList trail_list[MAXIMUM_TRAILS_PER_FINGER]; // OK!
611 };
612
613 /**
614  * Data structure to keep track of closest peer seen so far in find_successor()
615  */
616 struct Closest_Peer
617 {
618   /**
619    * 64 bit value of the peer
620    */
621   uint64_t value;
622
623   /**
624    * Trail id to reach to peer.
625    */
626   struct GNUNET_HashCode trail_id;
627
628   /**
629    * First hop, NULL in case of friend and my_identity
630    */
631   struct GNUNET_PeerIdentity next_hop;
632
633   /**
634    * Next destination. In case of friend and my_identity , it is same as next_hop
635    * In case of finger it is finger identity.
636    */
637   struct GNUNET_PeerIdentity next_destination;
638 };
639
640 /**
641  * Data structure to store the trail chosen to reach to finger.
642  */
643 struct Correct_Trail
644 {
645   /**
646    * First friend in the trail to reach finger.
647    */
648   struct FriendInfo friend;
649
650   /**
651    * Identifier of this trail.
652    */
653   struct GNUNET_HashCode trail_id;
654
655   /**
656    * Total number of peers in this trail.
657    */
658   unsigned int trail_length;
659 };
660
661 /**
662  * Task that sends FIND FINGER TRAIL requests. This task is started when we have
663  * get our first friend.
664  */
665 static GNUNET_SCHEDULER_TaskIdentifier find_finger_trail_task;
666
667 /**
668  * Identity of this peer.
669  */
670 static struct GNUNET_PeerIdentity my_identity;
671
672 /**
673  * Peer map of all the friends of a peer
674  */
675 static struct GNUNET_CONTAINER_MultiPeerMap *friend_peermap;
676
677 /**
678  * Hash map of all the fingers of a peer
679  */
680 static struct GNUNET_CONTAINER_MultiHashMap32 *finger_hashmap;
681
682 /**
683  * Handle to CORE.
684  */
685 static struct GNUNET_CORE_Handle *core_api;
686
687 /**
688  * The current finger index that we have want to find trail to. We start the
689  * search with value = 0, i.e. successor peer and then go to PREDCESSOR_FINGER_ID
690  * and decrement it. For any index 63 <= index < 0, if finger is same as successor,
691  * we reset this index to 0.
692  */
693 static unsigned int current_search_finger_index;
694
695
696 /**
697  * Called when core is ready to send a message we asked for
698  * out to the destination.
699  *
700  * @param cls the 'struct FriendInfo' of the target friend
701  * @param size number of bytes available in buf
702  * @param buf where the callee should write the message
703  * @return number of bytes written to buf
704  */
705 static size_t
706 core_transmit_notify (void *cls, size_t size, void *buf)
707 {
708   struct FriendInfo *peer = cls;
709   char *cbuf = buf;
710   struct P2PPendingMessage *pending;
711   size_t off;
712   size_t msize;
713
714   peer->th = NULL;
715   while ((NULL != (pending = peer->head)) &&
716          (0 == GNUNET_TIME_absolute_get_remaining (pending->timeout).rel_value_us))
717   {
718     peer->pending_count--;
719     GNUNET_CONTAINER_DLL_remove (peer->head, peer->tail, pending);
720     GNUNET_free (pending);
721   }
722   if (NULL == pending)
723   {
724     /* no messages pending */
725     return 0;
726   }
727   if (NULL == buf)
728   {
729     peer->th =
730         GNUNET_CORE_notify_transmit_ready (core_api, GNUNET_NO,
731                                            GNUNET_CORE_PRIO_BEST_EFFORT,
732                                            GNUNET_TIME_absolute_get_remaining
733                                            (pending->timeout), &peer->id,
734                                            ntohs (pending->msg->size),
735                                            &core_transmit_notify, peer);
736     GNUNET_break (NULL != peer->th);
737     return 0;
738   }
739   off = 0;
740   while ((NULL != (pending = peer->head)) &&
741          (size - off >= (msize = ntohs (pending->msg->size))))
742   {
743     GNUNET_STATISTICS_update (GDS_stats,
744                               gettext_noop
745                               ("# Bytes transmitted to other peers"), msize,
746                               GNUNET_NO);
747     memcpy (&cbuf[off], pending->msg, msize);
748     off += msize;
749     peer->pending_count--;
750     GNUNET_CONTAINER_DLL_remove (peer->head, peer->tail, pending);
751     GNUNET_free (pending);
752   }
753   if (peer->head != NULL)
754   {
755     peer->th =
756         GNUNET_CORE_notify_transmit_ready (core_api, GNUNET_NO,
757                                            GNUNET_CORE_PRIO_BEST_EFFORT,
758                                            GNUNET_TIME_absolute_get_remaining
759                                            (pending->timeout), &peer->id, msize,
760                                            &core_transmit_notify, peer);
761     GNUNET_break (NULL != peer->th);
762   }
763
764   return off;
765 }
766
767
768 /**
769  * FIXME: assertion fails at the end of this function. also in core_api.c at 1299.
770  * Transmit all messages in the friend's message queue.
771  *
772  * @param peer message queue to process
773  */
774 static void
775 process_friend_queue (struct FriendInfo *peer)
776 {
777   struct P2PPendingMessage *pending;
778
779   if (NULL == (pending = peer->head))
780     return;
781   if (NULL != peer->th)
782     return;
783
784   GNUNET_STATISTICS_update (GDS_stats,
785                             gettext_noop
786                             ("# Bytes of bandwidth requested from core"),
787                             ntohs (pending->msg->size), GNUNET_NO);
788
789   peer->th =
790       GNUNET_CORE_notify_transmit_ready (core_api, GNUNET_NO,
791                                          pending->importance,
792                                          GNUNET_TIME_absolute_get_remaining
793                                          (pending->timeout), &peer->id,
794                                          ntohs (pending->msg->size),
795                                          &core_transmit_notify, peer);
796   GNUNET_break (NULL != peer->th);
797 }
798
799
800 /**
801  * Construct a trail setup message and forward it to target_friend
802  * @param source_peer Source peer which wants to setup the trail
803  * @param ultimate_destination_finger Peer identity closest to this value will
804  *                                    be finger to @a source_peer
805  * @param next_destination Peer which should get the packet. I can be same as
806  *                         target_friend or different.
807  * @param target_friend Friend to which message is forwarded now.
808  * @param trail_length Total number of peers in trail setup so far.
809  * @param trail_peer_list Trail setup so far
810  * @param finger_map_index Index in finger map for which we are looking for finger.
811  * @param trail_id Unique identifier for the trail we are trying to setup.
812  * @param intermediate_trail_id Trail id of any intermediate trail we may have to
813  *                              traverse during trail setup. If not used then set to
814  *                              0.
815  */
816 void
817 GDS_NEIGHBOURS_send_trail_setup (const struct GNUNET_PeerIdentity source_peer,
818                                  uint64_t ultimate_destination_finger,
819                                  struct GNUNET_PeerIdentity next_destination,
820                                  struct FriendInfo *target_friend,
821                                  unsigned int trail_length,
822                                  const struct GNUNET_PeerIdentity *trail_peer_list,
823                                  unsigned int finger_map_index,
824                                  struct GNUNET_HashCode new_trail_id,
825                                  struct GNUNET_HashCode *intermediate_trail_id)
826 {
827   struct P2PPendingMessage *pending;
828   struct PeerTrailSetupMessage *tsm;
829   struct GNUNET_PeerIdentity *peer_list;
830   size_t msize;
831
832   msize = sizeof (struct PeerTrailSetupMessage) +
833           (trail_length * sizeof (struct GNUNET_PeerIdentity));
834
835   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
836   {
837     GNUNET_break (0);
838     return;
839   }
840
841   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
842   {
843     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
844                                 1, GNUNET_NO);
845   }
846
847   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
848   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
849   tsm = (struct PeerTrailSetupMessage *) &pending[1];
850   pending->msg = &tsm->header;
851   tsm->header.size = htons (msize);
852   tsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP);
853   tsm->ultimate_destination_finger = GNUNET_htonll (ultimate_destination_finger);
854   tsm->source_peer = source_peer;
855   tsm->next_destination = next_destination;
856   tsm->trail_length = htonl (trail_length);
857   tsm->finger_map_index = htonl (finger_map_index);
858   tsm->new_trail_id = new_trail_id;
859   if (NULL == intermediate_trail_id)
860     memset (&tsm->intermediate_trail_id, 0, sizeof (tsm->intermediate_trail_id));
861   else
862     tsm->intermediate_trail_id = *intermediate_trail_id;
863   if (trail_length > 0)
864   {
865     peer_list = (struct GNUNET_PeerIdentity *) &tsm[1];
866     memcpy (peer_list, trail_peer_list, trail_length * sizeof(struct GNUNET_PeerIdentity));
867   }
868
869   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
870   target_friend->pending_count++;
871   process_friend_queue (target_friend);
872 }
873
874
875 /**
876  * Construct a trail setup result message and forward it to target friend.
877  * @param destination_peer Peer which will get the trail to one of its finger.
878  * @param source_finger Peer to which the trail has been setup to.
879  * @param target_friend Friend to which this message should be forwarded.
880  * @param trail_length Numbers of peers in the trail.
881  * @param trail_peer_list Peers which are part of the trail from source to destination.
882  * @param finger_map_index Index in finger peer map
883  * @param trail_id Unique identifier of the trail.
884  */
885 void
886 GDS_NEIGHBOURS_send_trail_setup_result (struct GNUNET_PeerIdentity destination_peer,
887                                         struct GNUNET_PeerIdentity source_finger,
888                                         struct FriendInfo *target_friend,
889                                         unsigned int trail_length,
890                                         const struct GNUNET_PeerIdentity *trail_peer_list,
891                                         unsigned int finger_map_index,
892                                         struct GNUNET_HashCode trail_id)
893 {
894   struct P2PPendingMessage *pending;
895   struct PeerTrailSetupResultMessage *tsrm;
896   struct GNUNET_PeerIdentity *peer_list;
897   size_t msize;
898
899   msize = sizeof (struct PeerTrailSetupResultMessage) +
900           (trail_length * sizeof (struct GNUNET_PeerIdentity));
901
902   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
903   {
904     GNUNET_break (0);
905     return;
906   }
907
908   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
909   {
910     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
911                                 1, GNUNET_NO);
912   }
913
914   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
915   pending->importance = 0;
916   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
917   tsrm = (struct PeerTrailSetupResultMessage *) &pending[1];
918   pending->msg = &tsrm->header;
919   tsrm->header.size = htons (msize);
920   tsrm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP_RESULT);
921   tsrm->destination_peer = destination_peer;
922   tsrm->finger_identity = source_finger;
923   tsrm->trail_length = htonl (trail_length);
924   tsrm->finger_map_index = htonl (finger_map_index);
925   tsrm->trail_id = trail_id;
926
927   peer_list = (struct GNUNET_PeerIdentity *) &tsrm[1];
928   if (trail_length > 0)
929   {
930     memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
931   }
932   /* Send the message to chosen friend. */
933   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
934   target_friend->pending_count++;
935   process_friend_queue (target_friend);
936 }
937
938
939 /**
940  * Send trail rejection message to next_hop
941  * @param source_peer Source peer which is trying to setup the trail.
942  * @param finger_identity Peer closest to this value will be @a source_peer's finger
943  * @param congested_peer Peer which sent this message as it is congested.
944  * @param next_hop Peer to which we are forwarding this message.
945  * @param finger_map_index Index in finger peermap for which we are searching for finger.
946  * @param trail_peer_list Trails seen so far in trail setup before getting rejected
947  *                        by congested_peer
948  * @param trail_length Total number of peers in trail_peer_list
949  * @param trail_id Unique identifier of this trail.
950  * @param congestion_timeout Duration given by congested peer as an estimate of
951  *                           how long it may remain congested.
952  */
953 void
954 GDS_NEIGHBOURS_send_trail_rejection (struct GNUNET_PeerIdentity source_peer,
955                                      uint64_t finger_identity,
956                                      struct GNUNET_PeerIdentity congested_peer,
957                                      unsigned int finger_map_index,
958                                      struct GNUNET_PeerIdentity *trail_peer_list,
959                                      unsigned int trail_length,
960                                      struct GNUNET_HashCode trail_id,
961                                      struct FriendInfo *target_friend,
962                                      const struct GNUNET_TIME_Relative congestion_timeout)
963 {
964   struct PeerTrailRejectionMessage *trm;
965   struct P2PPendingMessage *pending;
966   struct GNUNET_PeerIdentity *peer_list;
967   size_t msize;
968
969   msize = sizeof (struct PeerTrailRejectionMessage) +
970           (trail_length * sizeof (struct GNUNET_PeerIdentity));
971
972   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
973   {
974     GNUNET_break (0);
975     return;
976   }
977
978   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
979   {
980     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
981                                 1, GNUNET_NO);
982   }
983
984   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
985   pending->importance = 0;
986   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
987   trm = (struct PeerTrailRejectionMessage *)&pending[1];
988   pending->msg = &trm->header;
989   trm->header.size = htons (msize);
990   trm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_REJECTION);
991   trm->source_peer = source_peer;
992   trm->congested_peer = congested_peer;
993   trm->congestion_time = congestion_timeout;
994   trm->finger_map_index = htonl (finger_map_index);
995   trm->trail_id = trail_id;
996
997   peer_list = (struct GNUNET_PeerIdentity *) &trm[1];
998   if (trail_length > 0)
999   {
1000     memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
1001   }
1002   /* Send the message to chosen friend. */
1003   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1004   target_friend->pending_count++;
1005   process_friend_queue (target_friend);
1006 }
1007
1008
1009 /**
1010  * Construct a verify successor message and forward it to target_friend.
1011  * @param source_peer Peer which wants to verify its successor.
1012  * @param successor Peer which is @a source_peer's current successor.
1013  * @param trail_id Identifier of trail to reach successor.
1014  * @param trail Trail to reach from source_peer to successor
1015  * @param trail_length Total number of peers in @a trail.
1016  * @param target_friend Message send to this friend.
1017  */
1018 void
1019 GDS_NEIGHBOURS_send_verify_successor_message (struct GNUNET_PeerIdentity source_peer,
1020                                               struct GNUNET_PeerIdentity successor,
1021                                               const struct GNUNET_HashCode trail_id,
1022                                               struct GNUNET_PeerIdentity *trail,
1023                                               unsigned int trail_length,
1024                                               struct FriendInfo *target_friend)
1025 {
1026   struct PeerVerifySuccessorMessage *vsm;
1027   struct P2PPendingMessage *pending;
1028   struct GNUNET_PeerIdentity *peer_list;
1029   size_t msize;
1030
1031   msize = sizeof (struct PeerVerifySuccessorMessage);
1032   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1033   {
1034     GNUNET_break (0);
1035     return;
1036   }
1037
1038   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1039   {
1040     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1041                                 1, GNUNET_NO);
1042   }
1043
1044   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
1045   pending->importance = 0;    /* FIXME */
1046   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1047   vsm = (struct PeerVerifySuccessorMessage *) &pending[1];
1048   pending->msg = &vsm->header;
1049   vsm->header.size = htons (msize);
1050   vsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR);
1051   vsm->source_peer = source_peer;
1052   vsm->successor = successor;
1053   vsm->trail_id = trail_id;
1054   vsm->trail_length = htonl (trail_length);
1055
1056   if (trail_length > 0)
1057   {
1058     peer_list = (struct GNUNET_PeerIdentity *) &vsm[1];
1059     memcpy (peer_list, trail, trail_length * sizeof (struct GNUNET_PeerIdentity));
1060   }
1061
1062   /* Send the message to chosen friend. */
1063   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1064   target_friend->pending_count++;
1065   process_friend_queue (target_friend);
1066 }
1067
1068
1069 /**
1070  * Construct a trail teardown message and send it to target_friend
1071  * @param source_peer Source of the trail.
1072  * @param destination_peer Destination of the trail.
1073  * @param trail_id Unique identifier of the trail.
1074  * @param trail_direction Direction of trail.
1075  * @param target_friend Friend to get this message.
1076  */
1077 void
1078 GDS_NEIGHBOURS_send_trail_teardown (struct GNUNET_PeerIdentity source_peer,
1079                                     struct GNUNET_PeerIdentity destination_peer,
1080                                     struct GNUNET_HashCode trail_id,
1081                                     enum GDS_ROUTING_trail_direction trail_direction,
1082                                     struct FriendInfo *target_friend)
1083 {
1084   struct PeerTrailTearDownMessage *ttdm;
1085   struct P2PPendingMessage *pending;
1086   size_t msize;
1087
1088   msize = sizeof (struct PeerTrailTearDownMessage);
1089
1090   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1091   {
1092     GNUNET_break (0);
1093     return;
1094   }
1095
1096   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1097   {
1098     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1099                                 1, GNUNET_NO);
1100   }
1101
1102   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
1103   pending->importance = 0;    /* FIXME */
1104   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1105   ttdm = (struct PeerTrailTearDownMessage *) &pending[1];
1106   pending->msg = &ttdm->header;
1107   ttdm->header.size = htons (msize);
1108   ttdm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_TEARDOWN);
1109   ttdm->source_peer = source_peer;
1110   ttdm->destination_peer = destination_peer;
1111   ttdm->TRAIL_ID = trail_id;
1112   ttdm->trail_direction = htonl (trail_direction);
1113
1114   /* Send the message to chosen friend. */
1115   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1116   target_friend->pending_count++;
1117   process_friend_queue (target_friend);
1118 }
1119
1120
1121 /**
1122  * Construct a verify successor message and send it to target_friend
1123  * @param destination_peer
1124  * @param source_successor
1125  * @param succ_predecessor
1126  * @param trail_id
1127  * @param trail
1128  * @param trail_length
1129  * @param target_friend
1130  */
1131 void
1132 GDS_NEIGHBOURS_send_verify_successor_result (struct GNUNET_PeerIdentity destination_peer,
1133                                              struct GNUNET_PeerIdentity source_successor,
1134                                              struct GNUNET_PeerIdentity succ_predecessor,
1135                                              struct GNUNET_HashCode trail_id,
1136                                              const struct GNUNET_PeerIdentity *trail,
1137                                              unsigned int trail_length,
1138                                              enum GDS_ROUTING_trail_direction trail_direction,
1139                                              struct FriendInfo *target_friend)
1140 {
1141   struct PeerVerifySuccessorResultMessage *vsmr;
1142   struct P2PPendingMessage *pending;
1143   struct GNUNET_PeerIdentity *peer_list;
1144   size_t msize;
1145
1146   msize = sizeof (struct PeerVerifySuccessorResultMessage) +
1147           (trail_length * sizeof(struct GNUNET_PeerIdentity));
1148
1149   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1150   {
1151     GNUNET_break (0);
1152     return;
1153   }
1154
1155   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1156   {
1157     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1158                                 1, GNUNET_NO);
1159   }
1160
1161   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
1162   pending->importance = 0;    /* FIXME */
1163   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1164   vsmr = (struct PeerVerifySuccessorResultMessage *) &pending[1];
1165   pending->msg = &vsmr->header;
1166   vsmr->header.size = htons (msize);
1167   vsmr->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR_RESULT);
1168   vsmr->destination_peer = destination_peer;
1169   vsmr->my_predecessor = succ_predecessor;
1170   vsmr->source_successor = source_successor;
1171   vsmr->trail_direction = htonl (trail_direction);
1172
1173   if (trail_length > 0)
1174   {
1175     peer_list = (struct GNUNET_PeerIdentity *) &vsmr[1];
1176     memcpy (peer_list, trail, trail_length * sizeof (struct GNUNET_PeerIdentity));
1177   }
1178
1179    /* Send the message to chosen friend. */
1180   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1181   target_friend->pending_count++;
1182   process_friend_queue (target_friend);
1183 }
1184
1185
1186 /**
1187  * Construct a notify new successor message and send it to target_friend
1188  * @param source_peer
1189  * @param new_successor
1190  * @param new_successor_trail
1191  * @param new_successor_trail_length
1192  * @param new_succesor_trail_id
1193  */
1194 void
1195 GDS_NEIGHBOURS_send_notify_new_successor (struct GNUNET_PeerIdentity source_peer,
1196                                           struct GNUNET_PeerIdentity new_successor,
1197                                           struct GNUNET_PeerIdentity *new_successor_trail,
1198                                           unsigned int new_successor_trail_length,
1199                                           struct GNUNET_HashCode new_succesor_trail_id,
1200                                           struct FriendInfo *target_friend)
1201 {
1202   struct PeerNotifyNewSuccessorMessage *nsm;
1203   struct P2PPendingMessage *pending;
1204   struct GNUNET_PeerIdentity *peer_list;
1205   size_t msize;
1206
1207   msize = sizeof (struct PeerNotifyNewSuccessorMessage) +
1208           (new_successor_trail_length * sizeof(struct GNUNET_PeerIdentity));
1209
1210   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1211   {
1212     GNUNET_break (0);
1213     return;
1214   }
1215
1216   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1217   {
1218     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1219                                 1, GNUNET_NO);
1220   }
1221
1222   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
1223   pending->importance = 0;    /* FIXME */
1224   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1225   nsm = (struct PeerNotifyNewSuccessorMessage *) &pending[1];
1226   pending->msg = &nsm->header;
1227   nsm->header.size = htons (msize);
1228   nsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_NEW_SUCCESSOR);
1229   nsm->source_peer = source_peer;
1230   nsm->destination_peer = new_successor;
1231   nsm->trail_length = htonl (new_successor_trail_length);
1232   nsm->trail_id = new_succesor_trail_id;
1233   if (new_successor_trail_length > 0)
1234   {
1235     peer_list = (struct GNUNET_PeerIdentity *) &nsm[1];
1236     memcpy (peer_list, new_successor_trail,
1237             new_successor_trail_length * sizeof (struct GNUNET_PeerIdentity));
1238   }
1239
1240    /* Send the message to chosen friend. */
1241   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1242   target_friend->pending_count++;
1243   process_friend_queue (target_friend);
1244 }
1245
1246
1247 /**
1248  * Construct an add_trail message and send it to target_friend
1249  * @param source_peer Source of the trail.
1250  * @param destination_peer Destination of the trail.
1251  * @param trail_id Unique identifer of the trail
1252  * @param trail Trail from @a source_peer to @a destination_peer
1253  * @param trail_length Total number of peers in @a trail.
1254  * @param target_friend Next peer to get this message.
1255  */
1256 void
1257 GDS_NEIGHBOURS_send_add_trail (struct GNUNET_PeerIdentity source_peer,
1258                                struct GNUNET_PeerIdentity destination_peer,
1259                                struct GNUNET_HashCode trail_id,
1260                                struct GNUNET_PeerIdentity *trail,
1261                                unsigned int trail_length,
1262                                struct FriendInfo *target_friend)
1263 {
1264   struct PeerAddTrailMessage *adm;
1265   struct GNUNET_PeerIdentity *peer_list;
1266   struct P2PPendingMessage *pending;
1267   size_t msize;
1268
1269   msize = sizeof (struct PeerAddTrailMessage) +
1270           (trail_length * sizeof(struct GNUNET_PeerIdentity));
1271
1272   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1273   {
1274     GNUNET_break (0);
1275     return;
1276   }
1277
1278   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1279   {
1280     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1281                                 1, GNUNET_NO);
1282   }
1283
1284   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
1285   pending->importance = 0;    /* FIXME */
1286   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1287   adm = (struct PeerAddTrailMessage *) &pending[1];
1288   pending->msg = &adm->header;
1289   adm->header.size = htons (msize);
1290   adm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_ADD_TRAIL);
1291   adm->source_peer = source_peer;
1292   adm->destination_peer = destination_peer;
1293   adm->trail_length = htonl (trail_length);
1294   adm->trail_id = trail_id;
1295
1296   if (trail_length > 0)
1297   {
1298     peer_list = (struct GNUNET_PeerIdentity *)&adm[1];
1299     memcpy (peer_list, trail, sizeof (struct GNUNET_PeerIdentity) * trail_length);
1300   }
1301
1302   /* Send the message to chosen friend. */
1303   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1304   target_friend->pending_count++;
1305   process_friend_queue (target_friend);
1306
1307 }
1308
1309
1310 /**
1311  * Merge into "teardown", add source and "last/new_first" in message struct.
1312  * Construct a trail compression message and send it to target_friend.
1313  * @param source_peer Source of the trail.
1314  * @param destination_finger Destination of trail.
1315  * @param trail_id Unique identifier of trail.
1316  * @param first_friend First hop in compressed trail to reach from source to finger
1317  * @param target_friend Next friend to get this message.
1318  */
1319 void
1320 GDS_NEIGHBOURS_send_trail_compression (struct GNUNET_PeerIdentity source_peer,
1321                                        struct GNUNET_PeerIdentity destination_peer,
1322                                        struct GNUNET_HashCode trail_id,
1323                                        struct GNUNET_PeerIdentity first_friend,
1324                                        struct FriendInfo *target_friend)
1325 {
1326   struct P2PPendingMessage *pending;
1327   struct PeerTrailCompressionMessage *tcm;
1328   size_t msize;
1329
1330   msize = sizeof (struct PeerTrailCompressionMessage);
1331
1332   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1333   {
1334     GNUNET_break (0);
1335     return;
1336   }
1337
1338   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1339   {
1340     GNUNET_STATISTICS_update (GDS_stats,
1341                               gettext_noop ("# P2P messages dropped due to full queue"),
1342                                                       1, GNUNET_NO);
1343   }
1344
1345   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
1346   pending->importance = 0;    /* FIXME */
1347   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1348   tcm = (struct PeerTrailCompressionMessage *) &pending[1];
1349   pending->msg = &tcm->header;
1350   tcm->header.size = htons (msize);
1351   tcm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_COMPRESSION);
1352   tcm->source_peer = source_peer;
1353   tcm->new_first_friend = first_friend;
1354   tcm->trail_id = trail_id;
1355   tcm->destination_peer = destination_peer;
1356
1357   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1358   target_friend->pending_count++;
1359   process_friend_queue (target_friend);
1360
1361 }
1362
1363
1364 /**
1365  * Seach my location in trail.
1366  * @param trail List of peers
1367  * @return my_index if found
1368  *         -1 if no entry found.
1369  */
1370 static int
1371 search_my_index (const struct GNUNET_PeerIdentity *trail,
1372                  int trail_length)
1373 {
1374   int i;
1375
1376   for (i = 0; i < trail_length; i++)
1377   {
1378     if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &trail[i]))
1379       return i;
1380   }
1381
1382   return -1;
1383 }
1384
1385
1386 /**
1387  * Iterate over the list of all the trails to reach Finger. In case the first
1388  * friend to reach the finger has crossed the trail threshold or is congested,
1389  * then don't select it. In case there multiple available good trails to reach
1390  * to Finger, choose the one with shortest trail length.
1391  * @param finger Finger
1392  * @return struct Correct_Trail which contains the first friend , trail id
1393  * and trail length. NULL in case none of the trails are free.
1394  */
1395 static struct Correct_Trail *
1396 select_trail_to_finger (struct FingerInfo *finger)
1397 {
1398   struct FriendInfo *friend;
1399   struct TrailList *iterator;
1400   struct Correct_Trail *finger_trail;
1401   int i;
1402
1403   if (0 == GNUNET_CRYPTO_cmp_peer_identity (&finger->finger_identity,
1404                                             &my_identity))
1405     return NULL;
1406
1407   finger_trail = GNUNET_new (struct Correct_Trail);
1408
1409   for (i = 0; i < finger->trails_count; i++)
1410   {
1411     iterator = &finger->trail_list[i];
1412     if (iterator->trail_length > 0)
1413     {
1414       friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap,
1415                                                   &iterator->trail_head->peer);
1416     }
1417     else
1418     {
1419       friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap,
1420                                                   &finger->finger_identity);
1421     }
1422
1423     if ((friend->trails_count < TRAILS_THROUGH_FRIEND_THRESHOLD)||
1424       ((0 == GNUNET_TIME_absolute_get_remaining (friend->congestion_timestamp).rel_value_us)))
1425     {
1426       if (iterator->trail_length == 0)
1427       {
1428         finger_trail->friend = *friend;
1429         //finger_trail->trail_id = 0;
1430         finger_trail->trail_length = 0;
1431         return finger_trail;
1432       }
1433
1434       if (finger_trail->trail_length > iterator->trail_length)
1435       {
1436         finger_trail->friend = *friend;
1437         finger_trail->trail_id = iterator->trail_id;
1438         finger_trail->trail_length = iterator->trail_length;
1439       }
1440     }
1441   }
1442
1443   return finger_trail;
1444 }
1445
1446
1447 /**
1448  * Select closest finger to value.
1449  * @param peer1 First peer
1450  * @param peer2 Second peer
1451  * @param value Value to be compare
1452  * @return Closest peer
1453  */
1454 static struct GNUNET_PeerIdentity *
1455 select_closest_finger (struct GNUNET_PeerIdentity *peer1,
1456                        struct GNUNET_PeerIdentity *peer2,
1457                        uint64_t value)
1458 {
1459 #if 0
1460   uint64_t peer1_value;
1461   uint64_t peer2_value;
1462
1463   memcpy (&peer1_value, peer1, sizeof (uint64_t));
1464   memcpy (&peer2_value, peer2, sizeof (uint64_t));
1465
1466   if ((peer1_value <= value) && (value <= peer2_value))
1467     return peer2;
1468   else if ((peer2_value <= value) && (value <= peer1_value))
1469     return peer1;
1470   else if ((peer1_value <= peer2_value) && (peer2_value <= value))
1471     return peer1;
1472   else if ((peer2_value <= peer1_value) && (peer1_value <= value))
1473     return peer2;
1474   else if ((value <= peer1_value) && (peer1_value <= peer2_value))
1475     return peer1;
1476   else /*if ((value <= peer2_value) && (peer2_value <= peer1_value))*/
1477     return peer2;
1478 #endif
1479   return NULL;
1480 }
1481
1482
1483 /**
1484  * Select closest predecessor to value.
1485  * @param peer1 First peer
1486  * @param peer2 Second peer
1487  * @param value Value to be compare
1488  * @return Closest peer
1489  */
1490 static struct GNUNET_PeerIdentity *
1491 select_closest_predecessor (struct GNUNET_PeerIdentity *peer1,
1492                             struct GNUNET_PeerIdentity *peer2,
1493                             uint64_t value)
1494 {
1495   #if 0
1496   uint64_t peer1_value;
1497   uint64_t peer2_value;
1498
1499   memcpy (&peer1_value, peer1, sizeof (uint64_t));
1500   memcpy (&peer2_value, peer2, sizeof (uint64_t));
1501
1502 #endif
1503   return NULL;
1504 }
1505
1506
1507 /**
1508  * Select the closest peer among two peers (which should not be same)
1509  * with respect to value and finger_map_index
1510  * @param peer1 First peer
1511  * @param peer2 Second peer
1512  * @param value Value relative to which we find the closest
1513  * @param finger_map_index Index in finger map. If equal to PREDECESSOR_FINGER_ID,
1514  *                         then we use different logic than other
1515  *                         finger_map_index
1516  * @return Closest peer among two peers.
1517  */
1518 static struct GNUNET_PeerIdentity *
1519 select_closest_peer (struct GNUNET_PeerIdentity *peer1,
1520                      struct GNUNET_PeerIdentity *peer2,
1521                      uint64_t value,
1522                      unsigned int finger_map_index)
1523 {
1524   struct GNUNET_PeerIdentity *closest_peer;
1525
1526   if (PREDECESSOR_FINGER_ID == finger_map_index)
1527     closest_peer = select_closest_predecessor (peer1, peer2, value);
1528   else
1529     closest_peer = select_closest_finger (peer1, peer2, value);
1530
1531   return closest_peer;
1532 }
1533
1534
1535 /**
1536  * Find the successor for destination_finger_value among my_identity, all my
1537  * friend and all my fingers. Don't consider friends or fingers
1538  * which are congested or have crossed the threshold.
1539  * @param destination_finger_value Peer closest to this value will be the next successor.
1540  * @param next_destination [out] Updated to friend identity in case a friend is
1541  *                               successor, updated to first friend to reach to finger
1542  *                               in case finger is the destination.
1543  * @param new_intermediate_trail_id [out] In case we finger is the @a next_destination,
1544  *                                then we updated the field with trail id to reach
1545  *                                to that finger.
1546  * @param finger_map_index Index in finger peermap for which we are
1547  *                         looking for a finger, to discern between
1548  *                         IS_PREDECESSOR or not.
1549  * @return
1550  */
1551 static struct GNUNET_PeerIdentity *
1552 find_successor (uint64_t destination_finger_value,
1553                 struct GNUNET_PeerIdentity *next_destination,
1554                 struct GNUNET_HashCode *new_intermediate_trail_id,
1555                 unsigned int finger_map_index)
1556 {
1557   struct Closest_Peer *successor;
1558   struct GNUNET_PeerIdentity *next_hop;
1559   struct GNUNET_CONTAINER_MultiPeerMapIterator *friend_iter;
1560   struct GNUNET_CONTAINER_MultiHashMap32Iterator *finger_iter;
1561   struct GNUNET_PeerIdentity *closest_peer;
1562   struct Correct_Trail *finger_trail;
1563   struct FriendInfo *friend;
1564   struct FingerInfo *finger;
1565   int i;
1566
1567   successor = GNUNET_new (struct Closest_Peer);
1568   memcpy (&successor->value, &my_identity, sizeof (uint64_t));
1569   //successor->trail_id = 0; /* FIXME:Default value for trail id */
1570   successor->next_hop = my_identity;
1571   successor->next_destination = my_identity;
1572
1573   friend_iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap);
1574   for (i= 0; i < GNUNET_CONTAINER_multipeermap_size (friend_peermap); i++)
1575   {
1576     GNUNET_assert (GNUNET_YES ==
1577       GNUNET_CONTAINER_multipeermap_iterator_next (friend_iter, NULL,
1578                                                   (const void **)&friend));
1579     if ((friend->trails_count > TRAILS_THROUGH_FRIEND_THRESHOLD)||
1580         (0 != GNUNET_TIME_absolute_get_remaining (friend->congestion_timestamp).rel_value_us))
1581       continue;
1582
1583     closest_peer = select_closest_peer (&my_identity, &friend->id,
1584                                         destination_finger_value,
1585                                         finger_map_index);
1586     if (0 == GNUNET_CRYPTO_cmp_peer_identity (closest_peer, &friend->id))
1587     {
1588       memcpy (&successor->value, &friend->id, sizeof (uint64_t));
1589       //successor->trail_id = 0;
1590       successor->next_hop = friend->id;
1591       successor->next_destination = friend->id;
1592     }
1593   }
1594
1595   finger_iter = GNUNET_CONTAINER_multihashmap32_iterator_create (finger_hashmap);
1596   for (i = 0; i < GNUNET_CONTAINER_multihashmap32_size (finger_hashmap); i++)
1597   {
1598     GNUNET_assert (GNUNET_YES ==
1599       GNUNET_CONTAINER_multihashmap32_iterator_next (finger_iter, NULL,
1600                                                      (void *)&finger));
1601    finger_trail = select_trail_to_finger (finger);
1602    if (NULL == finger_trail)
1603      continue;
1604
1605    closest_peer = select_closest_peer (&my_identity,
1606                                        &finger->finger_identity,
1607                                        destination_finger_value,
1608                                        finger_map_index);
1609    if (0 == GNUNET_CRYPTO_cmp_peer_identity (closest_peer,
1610                                              &finger->finger_identity))
1611    {
1612       memcpy (&successor->value, &finger->finger_identity, sizeof (uint64_t));
1613       successor->trail_id = finger_trail->trail_id;
1614       successor->next_hop = finger_trail->friend.id;
1615       successor->next_destination = finger->finger_identity;
1616     }
1617   }
1618
1619   next_destination = &successor->next_destination;
1620   new_intermediate_trail_id = &successor->trail_id;
1621   next_hop = &successor->next_hop;
1622
1623   return next_hop;
1624 }
1625
1626 /**
1627  * Construct a Put message and send it to target_peer.
1628  * @param key Key for the content
1629  * @param block_type Type of the block
1630  * @param options Routing options
1631  * @param desired_replication_level Desired replication count
1632  * @param current_destination Next current destination which will get this message.
1633  * @param current_source Source for @a current_destination
1634  * @param target_peer Peer to which this message will be forwarded.
1635  * @param hop_count Number of hops traversed so far.
1636  * @param put_path_length Total number of peers in @a put_path
1637  * @param put_path Number of peers traversed so far
1638  * @param expiration_time When does the content expire
1639  * @param data Content to store
1640  * @param data_size Size of content @a data in bytes
1641  */
1642 void
1643 GDS_NEIGHBOURS_send_put (const struct GNUNET_HashCode *key,
1644                          enum GNUNET_BLOCK_Type block_type,
1645                          enum GNUNET_DHT_RouteOption options,
1646                          uint32_t desired_replication_level,
1647                          struct GNUNET_PeerIdentity current_destination,
1648                          struct GNUNET_PeerIdentity current_source,
1649                          struct GNUNET_PeerIdentity *target_peer,
1650                          uint32_t hop_count,
1651                          uint32_t put_path_length,
1652                          struct GNUNET_PeerIdentity *put_path,
1653                          struct GNUNET_TIME_Absolute expiration_time,
1654                          const void *data, size_t data_size)
1655 {
1656
1657 }
1658
1659 /**
1660  * Construct a Get message and send it to target_peer.
1661  * @param key Key for the content
1662  * @param block_type Type of the block
1663  * @param options Routing options
1664  * @param desired_replication_level Desired replication count
1665  * @param current_destination Next current destination which will get this message.
1666  * @param current_source Source for @a current_destination
1667  * @param target_peer Peer to which this message will be forwarded.
1668  * @param hop_count Number of hops traversed so far.
1669  * @param data Content to store
1670  * @param data_size Size of content @a data in bytes
1671  * @param get_path_length Total number of peers in @a get_path
1672  * @param get_path Number of peers traversed so far
1673  */
1674 void
1675 GDS_NEIGHBOURS_send_get (const struct GNUNET_HashCode *key,
1676                          enum GNUNET_BLOCK_Type block_type,
1677                          enum GNUNET_DHT_RouteOption options,
1678                          uint32_t desired_replication_level,
1679                          struct GNUNET_PeerIdentity current_destination,
1680                          struct GNUNET_PeerIdentity current_source,
1681                          struct GNUNET_PeerIdentity *target_peer,
1682                          uint32_t hop_count,
1683                          uint32_t get_path_length,
1684                          struct GNUNET_PeerIdentity *get_path)
1685 {
1686
1687 }
1688
1689
1690 /**
1691  * Send the get result to requesting client.
1692  * @param key Key of the requested data.
1693  * @param type Block type
1694  * @param target_peer Next peer to forward the message to.
1695  * @param source_peer Peer which has the data for the key.
1696  * @param put_path_length Number of peers in @a put_path
1697  * @param put_path Path taken to put the data at its stored location.
1698  * @param get_path_length Number of peers in @a get_path
1699  * @param get_path Path taken to reach to the location of the key.
1700  * @param expiration When will this result expire?
1701  * @param data Payload to store
1702  * @param data_size Size of the @a data
1703  */
1704 void
1705 GDS_NEIGHBOURS_send_get_result (const struct GNUNET_HashCode *key,
1706                                 enum GNUNET_BLOCK_Type type,
1707                                 struct GNUNET_PeerIdentity *target_peer,
1708                                 struct GNUNET_PeerIdentity *source_peer,
1709                                 unsigned int put_path_length,
1710                                 const struct GNUNET_PeerIdentity *put_path,
1711                                 unsigned int get_path_length,
1712                                 struct GNUNET_PeerIdentity *get_path,
1713                                 struct GNUNET_TIME_Absolute expiration,
1714                                 const void *data, size_t data_size)
1715 {
1716
1717 }
1718
1719
1720 /**
1721  * Randomly choose one of your friends (which is not congested and have not crossed
1722  * trail threshold) from the friends_peer map
1723  * @return Friend Randomly chosen friend.
1724  *         NULL in case friend peermap is empty, or all the friends are either
1725  *              congested or have crossed trail threshold.
1726  */
1727 static struct FriendInfo *
1728 select_random_friend ()
1729 {
1730   unsigned int current_size;
1731   uint32_t index;
1732   unsigned int j = 0;
1733   struct GNUNET_CONTAINER_MultiPeerMapIterator *iter;
1734   struct GNUNET_PeerIdentity key_ret;
1735   struct FriendInfo *friend;
1736
1737   current_size = GNUNET_CONTAINER_multipeermap_size (friend_peermap);
1738   if (0 == current_size)
1739     return NULL;
1740
1741   index = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, current_size);
1742   iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap);
1743
1744   for (j = 0; j < index ; j++)
1745     GNUNET_assert (GNUNET_YES ==
1746                    GNUNET_CONTAINER_multipeermap_iterator_next (iter, NULL, NULL));
1747   do
1748   {
1749     if (j == current_size)
1750     {
1751       j = 0;
1752       GNUNET_CONTAINER_multipeermap_iterator_destroy (iter);
1753       iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap);
1754
1755     }
1756     GNUNET_assert (GNUNET_YES ==
1757                 GNUNET_CONTAINER_multipeermap_iterator_next (iter,
1758                                                              &key_ret,
1759                                                              (const void **)&friend));
1760
1761
1762     if ((TRAILS_THROUGH_FRIEND_THRESHOLD > friend->trails_count) &&
1763         (0 == GNUNET_TIME_absolute_get_remaining (friend->congestion_timestamp).rel_value_us))
1764     {
1765       break;
1766     }
1767     friend = NULL;
1768     j++;
1769   } while (j != index);
1770
1771   GNUNET_CONTAINER_multipeermap_iterator_destroy (iter);
1772   return friend;
1773 }
1774
1775
1776 /**
1777  * FIXME: pass current_search_finger_index as parameter
1778  * Compute finger_identity to which we want to setup the trail
1779  * @return finger_identity
1780  */
1781 static uint64_t
1782 compute_finger_identity()
1783 {
1784   uint64_t my_id64;
1785
1786   memcpy (&my_id64, &my_identity, sizeof (uint64_t));
1787   my_id64 = GNUNET_ntohll (my_id64);
1788   return (my_id64 + (unsigned long) pow (2, current_search_finger_index));
1789 }
1790
1791
1792 /**
1793  * Compute immediate predecessor identity in the network.
1794  * @return peer identity of immediate predecessor.
1795  */
1796 static uint64_t
1797 compute_predecessor_identity()
1798 {
1799   uint64_t my_id64;
1800
1801   memcpy (&my_id64, &my_identity, sizeof (uint64_t));
1802   my_id64 = GNUNET_ntohll (my_id64);
1803   return (my_id64 -1);
1804 }
1805
1806
1807 /*
1808  * Choose a random friend and start looking for the trail to reach to
1809  * finger identity through this random friend.
1810  *
1811  * @param cls closure for this task
1812  * @param tc the context under which the task is running
1813  */
1814 static void
1815 send_find_finger_trail_message (void *cls,
1816                                 const struct GNUNET_SCHEDULER_TaskContext *tc)
1817 {
1818   struct FriendInfo *target_friend;
1819   struct GNUNET_TIME_Relative next_send_time;
1820   struct GNUNET_HashCode trail_id;
1821   unsigned int finger_map_index;
1822   uint64_t finger_identity;
1823
1824   next_send_time.rel_value_us =
1825       DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us +
1826       GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
1827                                 DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us);
1828   find_finger_trail_task =
1829       GNUNET_SCHEDULER_add_delayed (next_send_time, &send_find_finger_trail_message,
1830                                     NULL);
1831
1832   target_friend = select_random_friend ();
1833   if (NULL == target_friend)
1834   {
1835     return;
1836   }
1837
1838   if (PREDECESSOR_FINGER_ID == current_search_finger_index)
1839   {
1840     finger_identity = compute_predecessor_identity();
1841   }
1842   else
1843   {
1844     finger_identity = compute_finger_identity();
1845   }
1846
1847   finger_map_index = current_search_finger_index;
1848
1849   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG,
1850                               &trail_id, sizeof (trail_id));
1851   GDS_NEIGHBOURS_send_trail_setup (my_identity, finger_identity,
1852                                    target_friend->id, target_friend, 0, NULL,
1853                                    finger_map_index, trail_id, NULL);
1854 }
1855
1856
1857 /**
1858  * In case there are already maximum number of possible trails to reach to a
1859  * finger, then check if the new trail's length is lesser than any of the
1860  * existing trails.
1861  * If yes then replace that old trail by new trail.
1862  *
1863  * Note: Here we are taking length as a parameter to choose the best possible
1864  * trail, but there could be other parameters also like:
1865  * 1. duration of existence of a trail - older the better.
1866  * 2. if the new trail is completely disjoint than the
1867  *    other trails, then may be choosing it is better.
1868  *
1869  * @param existing_finger
1870  * @param new_finger_trail
1871  * @param new_finger_trail_length
1872  * @param new_finger_trail_id
1873  */
1874 static void
1875 select_and_replace_trail (struct FingerInfo *existing_finger,
1876                           struct GNUNET_PeerIdentity *new_trail,
1877                           unsigned int new_trail_length,
1878                           struct GNUNET_HashCode new_trail_id)
1879 {
1880   struct TrailList *trail_list_iterator;
1881   unsigned int largest_trail_length;
1882   unsigned int largest_trail_index;
1883   struct Trail *trail_element;
1884   unsigned int i;
1885
1886   largest_trail_length = new_trail_length;
1887   largest_trail_index = MAXIMUM_TRAILS_PER_FINGER + 1;
1888
1889   GNUNET_assert (MAXIMUM_TRAILS_PER_FINGER == existing_finger->trails_count);
1890
1891   for (i = 0; i < existing_finger->trails_count; i++)
1892   {
1893     trail_list_iterator = &existing_finger->trail_list[i];
1894     if (trail_list_iterator->trail_length > largest_trail_length)
1895     {
1896       largest_trail_length = trail_list_iterator->trail_length;
1897       largest_trail_index = i;
1898     }
1899   }
1900
1901   if (largest_trail_index == (MAXIMUM_TRAILS_PER_FINGER + 1))
1902   {
1903     // tear down new trail: it's not better than the existing ones
1904     return;
1905   }
1906
1907   /* Send trail teardown message across the replaced trail. */
1908   struct TrailList *replace_trail = &existing_finger->trail_list[largest_trail_index];
1909   struct FriendInfo *target_friend =
1910       GNUNET_CONTAINER_multipeermap_get (friend_peermap,
1911                                          &replace_trail->trail_head->peer);
1912
1913   GDS_NEIGHBOURS_send_trail_teardown (my_identity,
1914                                       existing_finger->finger_identity,
1915                                       replace_trail->trail_id,
1916                                       GDS_ROUTING_SRC_TO_DEST, target_friend);
1917   /* Free the trail. */
1918   while (NULL != (trail_element = replace_trail->trail_head))
1919   {
1920     GNUNET_CONTAINER_DLL_remove (replace_trail->trail_head,
1921                                  replace_trail->trail_tail, trail_element);
1922     GNUNET_free (trail_element);
1923   }
1924
1925   /* Add new trial at that location. */
1926   i = 0;
1927   while (i < new_trail_length)
1928   {
1929     struct Trail *element = GNUNET_new (struct Trail);
1930     element->peer = new_trail[i];
1931
1932     GNUNET_CONTAINER_DLL_insert_tail (replace_trail->trail_head,
1933                                       replace_trail->trail_tail,
1934                                       element);
1935   }
1936 }
1937
1938
1939 /**
1940  * Check if the new trail to reach to finger is unique or do we already have
1941  * such a trail present for finger.
1942  * @param existing_finger Finger identity
1943  * @param new_trail New trail to reach @a existing_finger
1944  * @param trail_length Total number of peers in new_trail.
1945  * @return #GNUNET_YES if the new trail is unique
1946  *         #GNUNET_NO if same trail is already present.
1947  */
1948 static int
1949 is_new_trail_unique (struct FingerInfo *existing_finger,
1950                      struct GNUNET_PeerIdentity *new_trail,
1951                      unsigned int trail_length)
1952 {
1953   struct TrailList *trail_list_iterator;
1954   struct Trail *trail_element;
1955   int i;
1956   int j;
1957   int trail_unique = GNUNET_NO;
1958
1959   for (i = 0; i < existing_finger->trails_count; i++)
1960   {
1961     trail_list_iterator = &existing_finger->trail_list[i];
1962     if (trail_list_iterator->trail_length != trail_length)
1963       continue;
1964     trail_element = trail_list_iterator->trail_head;
1965     for (j = 0; j < trail_list_iterator->trail_length; j++)
1966     {
1967       if (0 != GNUNET_CRYPTO_cmp_peer_identity (&new_trail[j],
1968                                                 &trail_element->peer))
1969       {
1970         trail_unique = GNUNET_YES;
1971         break;
1972       }
1973     }
1974   }
1975   return trail_unique;
1976 }
1977
1978
1979 /**
1980  * Add a new trail to existing finger.
1981  * @param existing_finger
1982  * @param new_finger_trail
1983  * @param new_finger_trail_length
1984  * @param new_finger_trail_id
1985  */
1986 static void
1987 add_new_trail (struct FingerInfo *existing_finger,
1988                struct GNUNET_PeerIdentity *new_trail,
1989                unsigned int new_trail_length,
1990                struct GNUNET_HashCode new_trail_id)
1991 {
1992   struct TrailList *trail_list_iterator;
1993   struct FriendInfo *first_friend;
1994   int i;
1995
1996   if (GNUNET_NO == is_new_trail_unique (existing_finger, new_trail,
1997                                         new_trail_length))
1998   {
1999     return;
2000   }
2001
2002   // FIXME checking trail_head is NOT a valid way to verify an open slot
2003   for (i = 0; existing_finger->trail_list[i].trail_head != NULL; i++)
2004     GNUNET_assert (i < MAXIMUM_TRAILS_PER_FINGER);
2005
2006   trail_list_iterator = &existing_finger->trail_list[i];
2007
2008   if (new_trail_length > 0)
2009     first_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap,
2010                                                       &new_trail[0]);
2011   else
2012     first_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap,
2013                                                       &(existing_finger->finger_identity));
2014   first_friend->trails_count++;
2015   trail_list_iterator->first_friend_trail_count = first_friend->trails_count;
2016   trail_list_iterator->trail_length = new_trail_length;
2017
2018   for (i = 0; i < new_trail_length; i++)
2019   {
2020     struct Trail *element;
2021     element = GNUNET_new (struct Trail);
2022
2023     element->peer = new_trail[i];
2024     GNUNET_CONTAINER_DLL_insert_tail (trail_list_iterator->trail_head,
2025                                       trail_list_iterator->trail_tail,
2026                                       element);
2027   }
2028   existing_finger->trails_count++;
2029 }
2030
2031
2032 /**
2033  * Send trail teardown message on all trails associated with finger.
2034  * @param finger_to_be_removed
2035  */
2036 static void
2037 send_trail_teardown (struct FingerInfo *finger)
2038 {
2039   struct TrailList *trail_list_iterator;
2040   struct FriendInfo *target_friend;
2041   int i;
2042
2043   if (0 == GNUNET_CRYPTO_cmp_peer_identity (&finger->finger_identity, &my_identity)
2044      || (NULL != GNUNET_CONTAINER_multipeermap_get (friend_peermap,
2045                                                     &finger->finger_identity)))
2046     return;
2047
2048   for (i = 0; i < finger->trails_count; i++)
2049   {
2050     trail_list_iterator = &finger->trail_list[i];
2051     if (trail_list_iterator->trail_length > 0)
2052     {
2053       target_friend =
2054               GNUNET_CONTAINER_multipeermap_get (friend_peermap,
2055                                                  &trail_list_iterator->trail_head->peer);
2056       // check target_friend
2057       GDS_NEIGHBOURS_send_trail_teardown (my_identity, finger->finger_identity,
2058                                           trail_list_iterator->trail_id,
2059                                           GDS_ROUTING_SRC_TO_DEST,
2060                                           target_friend);
2061     }
2062   }
2063 }
2064
2065
2066 /**
2067  * Decrement the trail count of the first friend to reach the finger
2068  * In case finger is the friend, then decrement its trail count.
2069  * @param finger
2070  */
2071 static void
2072 decrement_friend_trail_count (struct FingerInfo *finger)
2073 {
2074   struct TrailList *trail_list_iterator;
2075   struct FriendInfo *target_friend;
2076   int i = 0;
2077
2078   if (0 == GNUNET_CRYPTO_cmp_peer_identity (&finger->finger_identity,
2079                                             &my_identity))
2080     return;
2081
2082   for (i = 0; i < finger->trails_count; i++)
2083   {
2084     trail_list_iterator = &finger->trail_list[i];
2085     if (trail_list_iterator->trail_length > 0)
2086       target_friend =
2087               GNUNET_CONTAINER_multipeermap_get (friend_peermap,
2088                                                  &trail_list_iterator->trail_head->peer);
2089     else
2090      target_friend =
2091               GNUNET_CONTAINER_multipeermap_get (friend_peermap,
2092                                                  &finger->finger_identity);
2093
2094     // check target_friend for NULL
2095     target_friend->trails_count--;
2096     trail_list_iterator->first_friend_trail_count--;
2097   }
2098   return;
2099 }
2100
2101
2102 /**
2103  * Free finger and its trail.
2104  * @param finger Finger to be freed.
2105  */
2106 static void
2107 free_finger (struct FingerInfo *finger)
2108 {
2109   struct TrailList *trail_list_iterator;
2110   struct Trail *trail_element;
2111   unsigned int i;
2112
2113   for (i = 0; i < finger->trails_count; i++)
2114   {
2115     trail_list_iterator = &finger->trail_list[i];
2116     while (NULL != (trail_element = trail_list_iterator->trail_head))
2117     {
2118       GNUNET_CONTAINER_DLL_remove (trail_list_iterator->trail_head,
2119                                    trail_list_iterator->trail_tail,
2120                                    trail_element);
2121       GNUNET_free (trail_element);
2122     }
2123   }
2124   GNUNET_free (finger);
2125 }
2126
2127
2128 /**
2129  * FIXME: merge into finger_table_add
2130  * FIXME: leave as simple a check
2131  * Check if new finger is closer than existing_finger. If both new finger and
2132  * existing finger are same then we may add a new trail (if there is space)
2133  * or choose the best trail among existing trails and new trails.
2134  * @param existing_finger Finger present in finger_peermap at @a finger_map_index
2135  *                        or NULL if none
2136  * @param new_finger_identity Peer identity of new finger.
2137  * FIXME: all the following params *should* not be necessary
2138  * @param new_finger_trail Trail to reach from source to new_finger.
2139  * @param new_finger_trail_length Total number of peers in @a new_finger_trail.
2140  * @param trail_id Unique identifier of trail.
2141  * @param finger_map_index Index in finger map.
2142  * @return #GNUNET_YES if the new finger is closest.
2143  *         #GNUNET_NO either new_finger and existing_finger are same, or
2144  *                    existing_finger is closest.
2145  */
2146 static int
2147 is_new_finger_closest (struct FingerInfo *existing_finger,
2148                        struct GNUNET_PeerIdentity new_finger_identity,
2149                        struct GNUNET_PeerIdentity *new_finger_trail,
2150                        unsigned int new_finger_trail_length,
2151                        struct GNUNET_HashCode new_finger_trail_id,
2152                        unsigned int finger_map_index)
2153 {
2154   struct GNUNET_PeerIdentity *closest_peer;
2155   uint64_t finger_identity_value;
2156   uint64_t my_id64;
2157
2158   if (NULL == existing_finger)
2159     return GNUNET_YES;
2160
2161   memcpy (&my_id64, &my_identity, sizeof (uint64_t));
2162   if (0 != GNUNET_CRYPTO_cmp_peer_identity (&(existing_finger->finger_identity),
2163                                             &new_finger_identity))
2164   {
2165     if (PREDECESSOR_FINGER_ID == finger_map_index)
2166       finger_identity_value = my_id64 - 1;
2167     else
2168       finger_identity_value = my_id64 + (unsigned long) pow (2, finger_map_index);
2169     closest_peer = select_closest_peer (&existing_finger->finger_identity,
2170                                         &new_finger_identity,
2171                                         finger_identity_value, finger_map_index);
2172
2173     if (0 == GNUNET_CRYPTO_cmp_peer_identity (&new_finger_identity, closest_peer))
2174     {
2175       GNUNET_assert (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity,
2176                                                            &new_finger_identity));
2177
2178       send_trail_teardown (existing_finger);
2179       decrement_friend_trail_count (existing_finger);
2180       free_finger (existing_finger);
2181       return GNUNET_YES;
2182     }
2183   }
2184   else
2185   {
2186     if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(existing_finger->finger_identity),
2187                                               &my_identity))
2188     {
2189       return GNUNET_NO;
2190     }
2191     if (NULL ==
2192         GNUNET_CONTAINER_multipeermap_get (friend_peermap,
2193                                             &(existing_finger->finger_identity)))
2194     {
2195       if (existing_finger->trails_count < MAXIMUM_TRAILS_PER_FINGER)
2196         add_new_trail (existing_finger, new_finger_trail,
2197                         new_finger_trail_length, new_finger_trail_id);
2198       else
2199         select_and_replace_trail (existing_finger, new_finger_trail,
2200                                   new_finger_trail_length, new_finger_trail_id);
2201     }
2202   }
2203   return GNUNET_NO;
2204 }
2205
2206
2207 /**
2208  * Add a new entry in finger hashmap at finger_map_index
2209  * @param finger_identity Peer Identity of new finger
2210  * @param finger_trail Trail to reach from me to finger (excluding both end points).
2211  * @param finger_trail_length Total number of peers in @a finger_trail.
2212  * @param trail_id Unique identifier of the trail.
2213  * @param finger_map_index Index in finger hashmap.
2214  * @return #GNUNET_OK if new entry is added
2215  *         #GNUNET_NO -- FIXME: need to check what value does hahsmap put
2216  *                       returns on failure.
2217  */
2218 static int
2219 add_new_entry (struct GNUNET_PeerIdentity finger_identity,
2220                struct GNUNET_PeerIdentity *finger_trail,
2221                unsigned int finger_trail_length,
2222                struct GNUNET_HashCode trail_id,
2223                unsigned int finger_map_index)
2224 {
2225   struct FingerInfo *new_entry;
2226   struct FriendInfo *first_trail_hop;
2227   struct TrailList *first_trail;
2228   int i = 0;
2229
2230   new_entry = GNUNET_new (struct FingerInfo);
2231   new_entry->finger_identity = finger_identity;
2232   new_entry->finger_map_index = finger_map_index;
2233   new_entry->trails_count = 1;
2234
2235   if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &finger_identity))
2236   {
2237     if (finger_trail_length > 0)
2238     {
2239       first_trail_hop = GNUNET_CONTAINER_multipeermap_get (friend_peermap,
2240                                                            &finger_trail[0]);
2241     }
2242     else
2243     {
2244       first_trail_hop = GNUNET_CONTAINER_multipeermap_get (friend_peermap,
2245                                                            &finger_identity);
2246     }
2247
2248     first_trail_hop->trails_count++;
2249     first_trail = &new_entry->trail_list[0];
2250     first_trail->first_friend_trail_count = first_trail_hop->trails_count;
2251
2252     while (i < finger_trail_length)
2253     {
2254       struct Trail *element = GNUNET_new (struct Trail);
2255
2256       element->next = NULL;
2257       element->prev = NULL;
2258       element->peer = finger_trail[i];
2259       GNUNET_CONTAINER_DLL_insert_tail (first_trail->trail_head,
2260                                         first_trail->trail_tail,
2261                                         element);
2262       i++;
2263     }
2264   }
2265
2266   return GNUNET_CONTAINER_multihashmap32_put (finger_hashmap,
2267                                               new_entry->finger_map_index,
2268                                               new_entry,
2269                                               GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
2270 }
2271
2272
2273 /**
2274  * Scan the trail to check if there is any other friend in the trail other than
2275  * first hop. If yes then shortcut the trail, send trail compression message to
2276  * peers which are no longer part of trail and send back the updated trail
2277  * and trail_length to calling function.
2278  * @param finger_identity Finger whose trail we will scan.
2279  * @param finger_trail [in, out] Trail to reach from source to finger,
2280  * @param finger_trail_length  Total number of peers in original finger_trail.
2281  * @param finger_trail_id Unique identifier of the finger trail.
2282  * @return updated trail length in case we shortcut the trail, else original
2283  *         trail length.
2284  */
2285 static int
2286 scan_and_compress_trail (struct GNUNET_PeerIdentity finger_identity,
2287                          struct GNUNET_PeerIdentity *trail,
2288                          unsigned int trail_length,
2289                          struct GNUNET_HashCode trail_id)
2290 {
2291   struct FriendInfo *target_friend;
2292   int i;
2293
2294   if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &finger_identity))
2295   {
2296     return 0;
2297   }
2298
2299   if (NULL != GNUNET_CONTAINER_multipeermap_get (friend_peermap, &finger_identity))
2300   {
2301     if (trail_length > 0)
2302     {
2303       target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap,
2304                                                        &trail[0]);
2305       GDS_NEIGHBOURS_send_trail_compression (my_identity, finger_identity,
2306                                            trail_id, finger_identity,
2307                                            target_friend);
2308       trail = NULL;
2309     }
2310     return 0;
2311   }
2312
2313   for (i = trail_length - 1; i > 0; i--)
2314   {
2315     if (NULL != GNUNET_CONTAINER_multipeermap_get (friend_peermap, &trail[i]))
2316     {
2317       struct FriendInfo *target_friend;
2318       int j = 0;
2319
2320       target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap,
2321                                                          &trail[0]);
2322       GDS_NEIGHBOURS_send_trail_compression (my_identity, finger_identity,
2323                                              trail_id, trail[i],
2324                                              target_friend);
2325
2326       // FIXME WARNING WARNING WARNING rewrite!!! consider directly creating a
2327       // struct TrailList (current) // struct Trial (after renaming).
2328
2329       /* Copy the trail from index i to index trail_length -1 and change
2330        trail length and return */
2331       while (i < trail_length)
2332       {
2333         memcpy (&trail[j], &trail[i], sizeof(struct GNUNET_PeerIdentity));
2334         j++;
2335         i++;
2336       }
2337       trail_length = j+1;
2338       break;
2339     }
2340   }
2341   return trail_length;
2342 }
2343
2344
2345 /**
2346  * Send verify successor message to your successor on all trails to reach
2347  * the successor.
2348  * @param successor My current successor
2349  */
2350 static void
2351 send_verify_successor_message (struct FingerInfo *successor)
2352 {
2353   struct TrailList *trail_list_iterator;
2354   struct GNUNET_HashCode trail_id;
2355   struct GNUNET_PeerIdentity next_hop;
2356   struct FriendInfo *target_friend;
2357   struct GNUNET_PeerIdentity *trail;
2358   unsigned int trail_length;
2359   int i;
2360   int j;
2361
2362   for (i = 0; i < MAXIMUM_TRAILS_PER_FINGER; i++)
2363   {
2364     trail_list_iterator = &successor->trail_list[i];
2365
2366 //      FIXME check if this entry in the trail list is valid!
2367 //     if (NULL == trail_list_iterator->SOMETHING)
2368 //       continue;
2369
2370     if (trail_list_iterator->trail_length > 0)
2371     {
2372       struct Trail *element;
2373
2374       trail_length = trail_list_iterator->trail_length;
2375       trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)
2376                              * trail_length);
2377       element = trail_list_iterator->trail_head;
2378       for (j = 0; j < trail_length; j++, element = element->next)
2379         trail[j] = element->peer;
2380       next_hop = trail_list_iterator->trail_head->peer;
2381     }
2382     else
2383     {
2384       trail = NULL;
2385       trail_length = 0;
2386       next_hop = successor->finger_identity;
2387     }
2388     trail_id = trail_list_iterator->trail_id;
2389     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
2390     // check friend for NULL
2391     GDS_NEIGHBOURS_send_verify_successor_message (my_identity,
2392                                                   successor->finger_identity,
2393                                                   trail_id, trail, trail_length,
2394                                                   target_friend);
2395     GNUNET_free_non_null (trail);
2396   }
2397 }
2398
2399
2400 /**
2401  * Check if there is already an entry in finger peermap for given finger map index.
2402  * If yes, then select the closest finger. If new and existing finger are same,
2403  * the check if you can store more trails. If yes then add trail, else keep the best
2404  * trails to reach to the finger. If the new finger is closest, add it.
2405  * Then, update current_search_finger_index.
2406  * @param new_finger_identity Peer Identity of new finger
2407  * @param new_finger_trail Trail to reach the new finger
2408  * @param new_finger_length Total number of peers in @a new_finger_trail.
2409  * @param finger_map_index Index in finger peermap.
2410  * @param new_finger_trail_id Unique identifier of @new_finger_trail.
2411  * @return #GNUNET_YES if the new entry is added
2412  *         #GNUNET_NO if new entry is not added, either it was discarded or
2413  *                    it was same as existing finger at finger map index.
2414  */
2415 static int
2416 finger_table_add (struct GNUNET_PeerIdentity new_finger_identity, // "finger_id"
2417                   struct GNUNET_PeerIdentity *new_finger_trail, // "trail"
2418                   unsigned int new_finger_trail_length,
2419                   unsigned int finger_map_index,
2420                   struct GNUNET_HashCode new_finger_trail_id)
2421 {
2422   struct FingerInfo *existing_finger;
2423   struct FingerInfo *successor;
2424   unsigned int new_entry_added = GNUNET_NO;
2425   int new_finger_updated_trail_length; // new_finger_trail_length
2426
2427   new_finger_updated_trail_length =
2428        scan_and_compress_trail (new_finger_identity, new_finger_trail,
2429                                 new_finger_trail_length, new_finger_trail_id);
2430
2431   existing_finger = GNUNET_CONTAINER_multihashmap32_get (finger_hashmap,
2432                                                          finger_map_index);
2433
2434   if  (GNUNET_YES == is_new_finger_closest (existing_finger,
2435                                             new_finger_identity,
2436                                             new_finger_trail,
2437                                             new_finger_updated_trail_length,
2438                                             new_finger_trail_id, finger_map_index))
2439   {
2440     // send_destroy_existing_finger ...
2441     // free_exisiting_finger ...
2442     GNUNET_assert (GNUNET_YES == add_new_entry (new_finger_identity,
2443                                                 new_finger_trail,
2444                                                 new_finger_updated_trail_length,
2445                                                 new_finger_trail_id,
2446                                                 finger_map_index));
2447     new_entry_added = GNUNET_YES;
2448   }
2449 //   else if if_new_finger_equal () {
2450 //
2451 //   }
2452 //   else // existing finger is closest
2453 //   {
2454 //
2455 //   }
2456
2457   // FIXME move block to "update_succesor"
2458   {
2459     successor = GNUNET_CONTAINER_multihashmap32_get (finger_hashmap, 0);
2460     // WARNING FIXME check that current_search_finger_index does not go out of bounds
2461     if (0 == finger_map_index)
2462     {
2463       current_search_finger_index = PREDECESSOR_FINGER_ID;
2464
2465       if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &new_finger_identity))
2466       {
2467         send_verify_successor_message (successor);
2468       }
2469     }
2470     else if (0 == GNUNET_CRYPTO_cmp_peer_identity (&new_finger_identity,
2471                                                   &(successor->finger_identity)))
2472     {
2473       current_search_finger_index = 0;
2474     }
2475     else
2476       current_search_finger_index = current_search_finger_index - 1;
2477   }
2478
2479   return new_entry_added;
2480 }
2481
2482
2483 /**
2484  * Core handler for P2P put messages.
2485  * @param cls closure
2486  * @param peer sender of the request
2487  * @param message message
2488  * @return #GNUNET_OK to keep the connection open,
2489  *         #GNUNET_SYSERR to close it (signal serious error)
2490  */
2491 static int
2492 handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer,
2493                     const struct GNUNET_MessageHeader *message)
2494 {
2495   return GNUNET_OK;
2496 }
2497
2498
2499 /**
2500  * Core handler for p2p get requests.
2501  *
2502  * @param cls closure
2503  * @param peer sender of the request
2504  * @param message message
2505  * @return #GNUNET_OK to keep the connection open,
2506  *         #GNUNET_SYSERR to close it (signal serious error)
2507  */
2508 static int
2509 handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer,
2510                     const struct GNUNET_MessageHeader *message)
2511 {
2512   return GNUNET_OK;
2513 }
2514
2515
2516 /**
2517  * Core handler for get result
2518  * @param cls closure
2519  * @param peer sender of the request
2520  * @param message message
2521  * @return #GNUNET_OK to keep the connection open,
2522  *         #GNUNET_SYSERR to close it (signal serious error)
2523  */
2524 static int
2525 handle_dht_p2p_get_result (void *cls, const struct GNUNET_PeerIdentity *peer,
2526                            const struct GNUNET_MessageHeader *message)
2527 {
2528   return GNUNET_OK;
2529 }
2530
2531
2532 /* Core handle for PeerTrailSetupMessage.
2533  * @param cls closure
2534  * @param message message
2535  * @param peer peer identity this notification is about
2536  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
2537  */
2538 static int
2539 handle_dht_p2p_trail_setup (void *cls, const struct GNUNET_PeerIdentity *peer,
2540                             const struct GNUNET_MessageHeader *message)
2541 {
2542   struct PeerTrailSetupMessage *trail_setup;
2543   struct GNUNET_PeerIdentity *trail_peer_list;
2544   struct GNUNET_PeerIdentity next_destination; // "local_best_known_destination"
2545   struct GNUNET_PeerIdentity *current_destination;
2546   struct GNUNET_PeerIdentity *next_hop;
2547   struct GNUNET_PeerIdentity next_peer;
2548   struct FriendInfo *target_friend;
2549   struct GNUNET_PeerIdentity source;
2550   uint64_t ultimate_destination_finger_value;
2551   struct GNUNET_HashCode new_intermediate_trail_id;
2552   //struct GNUNET_HashCode *intermediate_trail_id;
2553   struct GNUNET_HashCode new_trail_id;
2554   unsigned int finger_map_index;
2555   uint32_t trail_length;
2556   size_t msize;
2557
2558   msize = ntohs (message->size);
2559   /* There are PeerId's appended to the end of the message! */
2560   if (msize < sizeof (struct PeerTrailSetupMessage))
2561   {
2562     GNUNET_break_op (0);
2563     return GNUNET_YES;
2564   }
2565
2566   trail_setup = (struct PeerTrailSetupMessage *) message;
2567   trail_length = ntohl (trail_setup->trail_length); // (msize - sizeof (msg)) / sizeof(PI)
2568   // if ((msize - sizeof (msg)) % sizeof(PI) != 0)
2569   if ((msize != sizeof (struct PeerTrailSetupMessage) +
2570        trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
2571        (trail_length >
2572         GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2573   {
2574     GNUNET_break_op (0);
2575     return GNUNET_OK;
2576   }
2577
2578   trail_peer_list = (struct GNUNET_PeerIdentity *)&trail_setup[1];
2579   current_destination = &trail_setup->next_destination;
2580   new_trail_id = trail_setup->new_trail_id;
2581   ultimate_destination_finger_value = GNUNET_ntohll (trail_setup->ultimate_destination_finger);
2582   source = trail_setup->source_peer;
2583   finger_map_index = ntohl (trail_setup->finger_map_index);
2584   //intermediate_trail_id = &trail_setup->intermediate_trail_id;
2585   
2586   if (GNUNET_YES == GDS_ROUTING_threshold_reached())
2587   {
2588     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, peer);
2589     GDS_NEIGHBOURS_send_trail_rejection (source, ultimate_destination_finger_value,
2590                                          my_identity, finger_map_index,
2591                                          trail_peer_list, trail_length,
2592                                          new_trail_id, target_friend,
2593                                          CONGESTION_TIMEOUT);
2594     return GNUNET_OK;
2595   }
2596
2597   next_hop = find_successor (ultimate_destination_finger_value, &next_destination,
2598                              &new_intermediate_trail_id, finger_map_index);
2599
2600   /* Are we just a part of a trail towards a finger? */
2601   if (0 != (GNUNET_CRYPTO_cmp_peer_identity(&my_identity, current_destination)))
2602   {
2603 //    struct GNUNET_PeerIdentity *closest_peer;
2604 //     struct GNUNET_PeerIdentity *peer1 =
2605 //         GDS_ROUTING_get_next_hop (intermediate_trail_id,
2606 //                                   GDS_ROUTING_SRC_TO_DEST);
2607     /* Is next_destination better than the original best_known_dest? */
2608     // BIG FIXME START
2609 //     if (0 != GNUNET_CRYPTO_cmp_peer_identity (next_destination,
2610 //                                               current_destination))
2611 //     {
2612 //        closest_peer = select_closest_peer (peer1, next_hop,
2613 //                                            ultimate_destination_finger_value,
2614 //                                            finger_map_index);
2615 //     }
2616 //     if (0 == GNUNET_CRYPTO_cmp_peer_identity (peer1, closest_peer) ||
2617 //         (0 == GNUNET_CRYPTO_cmp_peer_identity (peer1, next_hop)))
2618 //     {
2619 //       next_hop = peer1;
2620 //       next_destination = *current_destination;
2621 //       new_intermediate_trail_id = intermediate_trail_id;
2622 //     }
2623     // BIG FIXME END
2624   }
2625
2626   GNUNET_assert (NULL != next_hop);
2627   /* Am I the final destination? */
2628   if (0 == (GNUNET_CRYPTO_cmp_peer_identity (next_hop, &my_identity)))
2629   {
2630     if (0 == trail_length)
2631       memcpy (&next_peer, &source, sizeof (struct GNUNET_PeerIdentity));
2632     else
2633       memcpy (&next_peer, &trail_peer_list[trail_length-1], sizeof (struct GNUNET_PeerIdentity));
2634
2635     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_peer);
2636     GDS_NEIGHBOURS_send_trail_setup_result (source,
2637                                             my_identity,
2638                                             target_friend, trail_length,
2639                                             trail_peer_list,
2640                                             finger_map_index, new_trail_id);
2641   }
2642   else
2643   {
2644     struct GNUNET_PeerIdentity peer_list[trail_length + 1];
2645
2646     memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
2647     peer_list[trail_length] = my_identity;
2648     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2649     GDS_NEIGHBOURS_send_trail_setup (source,
2650                                      ultimate_destination_finger_value,
2651                                      next_destination,
2652                                      target_friend, trail_length + 1, peer_list,
2653                                      finger_map_index, new_trail_id,
2654                                      &new_intermediate_trail_id);
2655   }
2656   return GNUNET_OK;
2657 }
2658
2659
2660 /**
2661  * Core handle for p2p trail construction result messages.
2662  * @param closure
2663  * @param message message
2664  * @param peer peer identity this notification is about
2665  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
2666  */
2667 static int
2668 handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *peer,
2669                                   const struct GNUNET_MessageHeader *message)
2670 {
2671   struct PeerTrailSetupResultMessage *trail_result;
2672   struct GNUNET_PeerIdentity *trail_peer_list;
2673   struct GNUNET_PeerIdentity destination_peer;
2674   struct GNUNET_PeerIdentity finger_identity;
2675   uint32_t trail_length;
2676   uint32_t finger_map_index;
2677   struct GNUNET_HashCode trail_id;
2678   size_t msize;
2679
2680   msize = ntohs (message->size);
2681   if (msize < sizeof (struct PeerTrailSetupResultMessage))
2682   {
2683     GNUNET_break_op (0);
2684     return GNUNET_YES;
2685   }
2686
2687   trail_result = (struct PeerTrailSetupResultMessage *) message;
2688
2689   // calculate trail_length with message size, check for % 0
2690   trail_length = ntohl (trail_result->trail_length);
2691   if ((msize !=
2692        sizeof (struct PeerTrailSetupResultMessage) +
2693        trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
2694        (trail_length >
2695         GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2696   {
2697     GNUNET_break_op (0);
2698     return GNUNET_YES;
2699   }
2700
2701   finger_map_index = htonl (trail_result->finger_map_index);
2702   destination_peer = trail_result->destination_peer;
2703   finger_identity = trail_result->finger_identity;
2704   trail_id = trail_result->trail_id;
2705   trail_peer_list = (struct GNUNET_PeerIdentity *) &trail_result[1];
2706
2707   // FIXME: check that trail_peer_list[my_index + 1] == peer or
2708   // my_index == trail_length - 1 AND finger_identity == peer
2709
2710   /* Am I the one who initiated the query? */
2711   if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&destination_peer,
2712                                              &my_identity)))
2713   {
2714     finger_table_add (finger_identity, trail_peer_list,
2715                       trail_length,
2716                       finger_map_index, trail_id);
2717     return GNUNET_YES;
2718   }
2719
2720   struct GNUNET_PeerIdentity next_hop;
2721   struct FriendInfo *target_friend;
2722   int my_index;
2723
2724   my_index = search_my_index(trail_peer_list, trail_length);
2725   if (-1 == my_index)
2726   {
2727     GNUNET_break_op(0);
2728     return GNUNET_SYSERR;
2729   }
2730
2731
2732   if (my_index == 0)
2733     next_hop = trail_result->destination_peer;
2734   else
2735     next_hop = trail_peer_list[my_index - 1];
2736
2737   if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&(trail_result->destination_peer),
2738                                                &(trail_result->finger_identity))))
2739   {
2740     GDS_ROUTING_add (trail_id, next_hop, *peer);
2741   }
2742
2743   target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
2744   GDS_NEIGHBOURS_send_trail_setup_result (destination_peer, finger_identity,
2745                                           target_friend, trail_length, trail_peer_list,
2746                                           finger_map_index, trail_id);
2747   return GNUNET_OK;
2748 }
2749
2750
2751 /**
2752  * Invert the trail.
2753  * @param trail Trail to be inverted
2754  * @param trail_length Total number of peers in the trail.
2755  * @return Updated trail
2756  */
2757 static struct GNUNET_PeerIdentity *
2758 invert_trail (struct GNUNET_PeerIdentity *trail,
2759               unsigned int trail_length)
2760 {
2761   int i;
2762   int j;
2763   struct GNUNET_PeerIdentity *inverted_trail;
2764
2765   inverted_trail = GNUNET_malloc (sizeof(struct GNUNET_PeerIdentity) *
2766                                   trail_length);
2767   i = 0;
2768   j = trail_length - 1;
2769   while (i < trail_length)
2770   {
2771     inverted_trail[i] = trail[j];
2772     i++;
2773     j--;
2774   }
2775   return inverted_trail;
2776 }
2777
2778
2779 /**
2780  * Check if the new finger can be our predecessor. If yes then update predecessor
2781  *
2782  * @param new_finger
2783  * @param new_finger_trail
2784  * @param new_finger_trail_length
2785  * @return
2786  */
2787 static int
2788 is_new_entry_correct_predecessor (struct FingerInfo *my_predecessor,
2789                                 struct GNUNET_PeerIdentity new_finger,
2790                                 struct GNUNET_PeerIdentity *new_finger_trail,
2791                                 unsigned int new_finger_trail_length)
2792 {
2793   struct GNUNET_PeerIdentity *updated_trail;
2794   struct GNUNET_HashCode new_trail_id;
2795
2796   updated_trail =  invert_trail (new_finger_trail, new_finger_trail_length);
2797   if (GNUNET_YES == is_new_finger_closest (my_predecessor, new_finger,
2798                                            new_finger_trail,
2799                                            new_finger_trail_length,
2800                                            new_trail_id, PREDECESSOR_FINGER_ID))
2801   {
2802     add_new_entry (new_finger, updated_trail, new_finger_trail_length,
2803                    new_trail_id, PREDECESSOR_FINGER_ID);
2804     /* FIXME: check where you send add trail message */
2805     return GNUNET_YES;
2806   }
2807   return GNUNET_NO;
2808 }
2809
2810 /**
2811  * In case the source peer of verify successor message is not my successor,
2812  * then construct a trail from source peer to my current predecessor.
2813  * @param my_predecessor my current predecessor.
2814  * @param current_trail Trail from source to me.
2815  * @param current_trail_length Total number of peers in @a current_trail
2816  * @param new_trail_length [out] Total number of peers in updated trail.
2817  * @return Updated trail from source peer to my_predecessor.
2818  */
2819 static struct GNUNET_PeerIdentity *
2820 trail_source_to_my_predecessor (struct FingerInfo *my_predecessor,
2821                                 struct GNUNET_PeerIdentity *current_trail,
2822                                 unsigned int current_trail_length,
2823                                 unsigned int *new_trail_length)
2824 {
2825   struct GNUNET_PeerIdentity *new_trail;
2826   struct TrailList *trail_list_iterator;
2827   struct Trail *trail_iterator;
2828   unsigned int i;
2829   unsigned int j;
2830   unsigned int shortest_trail_length = 0;
2831   unsigned int trail_index = 0;
2832
2833   for (i = 0; i < my_predecessor->trails_count; i++)
2834   {
2835     trail_list_iterator = &my_predecessor->trail_list[i];
2836     if (trail_list_iterator->trail_length > shortest_trail_length)
2837       continue;
2838     shortest_trail_length = trail_list_iterator->trail_length;
2839     trail_index = i;
2840   }
2841
2842   *new_trail_length = current_trail_length + shortest_trail_length + 1;
2843   new_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) *
2844                              *new_trail_length);
2845   memcpy (new_trail, current_trail,
2846          current_trail_length * sizeof (struct GNUNET_PeerIdentity));
2847   new_trail[current_trail_length + 1] = my_identity;
2848
2849   i = 0;
2850   j = current_trail_length + 1;
2851   trail_list_iterator = &my_predecessor->trail_list[trail_index];
2852   trail_iterator = trail_list_iterator->trail_head;
2853   while ( i < shortest_trail_length)
2854   {
2855     new_trail[j] = trail_iterator->peer;
2856     j++;
2857     i++;
2858     trail_iterator = trail_iterator->next;
2859   }
2860
2861   *new_trail_length = j;
2862   return new_trail;
2863 }
2864
2865
2866 /**
2867  * Core handle for p2p verify successor messages.
2868  * @param cls closure
2869  * @param message message
2870  * @param peer peer identity this notification is about
2871  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
2872  */
2873 static int
2874 handle_dht_p2p_verify_successor(void *cls, const struct GNUNET_PeerIdentity *peer,
2875                                 const struct GNUNET_MessageHeader *message)
2876 {
2877   struct PeerVerifySuccessorMessage *vsm;
2878   struct GNUNET_PeerIdentity successor;
2879   struct GNUNET_PeerIdentity source_peer;
2880   struct GNUNET_PeerIdentity *next_hop;
2881   struct FriendInfo *target_friend;
2882   struct GNUNET_HashCode trail_id;
2883   struct FingerInfo *my_predecessor;
2884   struct GNUNET_PeerIdentity *trail;
2885   struct GNUNET_PeerIdentity *new_trail;
2886   unsigned int trail_length;
2887   unsigned int new_trail_length;
2888   size_t msize;
2889
2890   msize = ntohs (message->size);
2891   if (msize != sizeof (struct PeerVerifySuccessorMessage))
2892   {
2893     GNUNET_break_op (0);
2894     return GNUNET_YES;
2895   }
2896
2897   vsm = (struct PeerVerifySuccessorMessage *) message;
2898   trail_length = ntohl (vsm->trail_length);
2899   if ((msize != sizeof (struct PeerVerifySuccessorMessage) +
2900                trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
2901       (trail_length > GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2902   {
2903     GNUNET_break_op (0);
2904     return GNUNET_YES;
2905   }
2906   trail = (struct GNUNET_PeerIdentity *)&vsm[1];
2907   source_peer = vsm->source_peer;
2908   successor = vsm->successor;
2909   trail_id = vsm->trail_id;
2910
2911   if(0 != (GNUNET_CRYPTO_cmp_peer_identity (&successor, &my_identity)))
2912   {
2913     next_hop = GDS_ROUTING_get_next_hop (trail_id, GDS_ROUTING_SRC_TO_DEST);
2914     if (NULL == next_hop)
2915     {
2916       GNUNET_break (0);
2917       return GNUNET_SYSERR;
2918     }
2919     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2920     GDS_NEIGHBOURS_send_verify_successor_message (source_peer, successor,
2921                                                   trail_id, trail, trail_length,
2922                                                   target_friend);
2923     return GNUNET_OK;
2924   }
2925
2926   my_predecessor = GNUNET_CONTAINER_multihashmap32_get (finger_hashmap,
2927                                                         PREDECESSOR_FINGER_ID);
2928   target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, peer);
2929   if (GNUNET_NO == is_new_entry_correct_predecessor (my_predecessor, source_peer,
2930                                                      trail, trail_length))
2931   {
2932     if (0 != GNUNET_CRYPTO_cmp_peer_identity (&source_peer,
2933                                               &my_predecessor->finger_identity))
2934     {
2935       new_trail = trail_source_to_my_predecessor (my_predecessor, trail,
2936                                                   trail_length, &new_trail_length);
2937     }
2938   }
2939   else
2940   {
2941     my_predecessor = GNUNET_CONTAINER_multihashmap32_get (finger_hashmap,
2942                                                           PREDECESSOR_FINGER_ID);
2943     GDS_NEIGHBOURS_send_add_trail (my_predecessor->finger_identity,
2944                                    source_peer, trail_id,
2945                                    trail, trail_length,
2946                                    target_friend);
2947     new_trail_length = trail_length;
2948     new_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) *
2949                                new_trail_length);
2950     memcpy (new_trail, trail, sizeof (struct GNUNET_PeerIdentity) *
2951                               trail_length);
2952   }
2953
2954   GDS_NEIGHBOURS_send_verify_successor_result (source_peer, my_identity,
2955                                                my_predecessor->finger_identity,
2956                                                trail_id, new_trail,
2957                                                new_trail_length,
2958                                                GDS_ROUTING_DEST_TO_SRC,
2959                                                target_friend);
2960   return GNUNET_OK;
2961 }
2962
2963
2964 /**
2965  * FIXME: I will keep the logic to remove the old trail to reach from me to
2966  * my old successor here and move adding a new trail from me to new successor to notify
2967  * new successor. And in case if the new successor also take it as predecessor
2968  * then call add_trail.
2969  * Core handle for p2p verify successor result messages.
2970  * @param cls closure
2971  * @param message message
2972  * @param peer peer identity this notification is about
2973  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
2974  */
2975 static int
2976 handle_dht_p2p_verify_successor_result(void *cls, const struct GNUNET_PeerIdentity *peer,
2977                                        const struct GNUNET_MessageHeader *message)
2978 {
2979   struct PeerVerifySuccessorResultMessage *vsrm;
2980   enum GDS_ROUTING_trail_direction trail_direction;
2981   struct GNUNET_HashCode trail_id;
2982   unsigned int new_trail_length;
2983   struct GNUNET_PeerIdentity *new_trail;
2984   struct GNUNET_PeerIdentity destination_peer;
2985   struct GNUNET_PeerIdentity my_new_successor;
2986   struct GNUNET_PeerIdentity old_successor;
2987   struct GNUNET_PeerIdentity *next_hop;
2988   struct FriendInfo *target_friend;
2989   size_t msize;
2990
2991   msize = ntohs (message->size);
2992   if (msize != sizeof (struct PeerVerifySuccessorResultMessage))
2993   {
2994     GNUNET_break_op (0);
2995     return GNUNET_YES;
2996   }
2997   vsrm = (struct PeerVerifySuccessorResultMessage *) message;
2998   new_trail_length = ntohl (vsrm->trail_length);
2999   trail_direction = ntohl (vsrm->trail_direction);
3000   trail_id = vsrm->trail_id;
3001
3002   if ((msize !=
3003        sizeof (struct PeerVerifySuccessorResultMessage) +
3004        new_trail_length *
3005        sizeof (struct GNUNET_PeerIdentity)) ||
3006        (new_trail_length >
3007        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
3008   {
3009     GNUNET_break_op (0);
3010     return GNUNET_YES;
3011   }
3012
3013   new_trail = (struct GNUNET_PeerIdentity *) &vsrm[1];
3014   destination_peer = vsrm->destination_peer;
3015   my_new_successor = vsrm->my_predecessor;
3016   old_successor = vsrm->source_successor;
3017
3018   if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&destination_peer, &my_identity)))
3019   {
3020     struct GNUNET_HashCode new_finger_trail_id;
3021     /* FIXME: generate a new trail id. */
3022     if (GNUNET_YES == finger_table_add (my_new_successor,
3023                                         new_trail,
3024                                         new_trail_length,
3025                                         PREDECESSOR_FINGER_ID, new_finger_trail_id))
3026     {
3027       if (new_trail_length > 0)
3028         target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap,
3029                                                            &new_trail[0]);
3030       else
3031         target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap,
3032                                                            peer);
3033       GDS_NEIGHBOURS_send_trail_teardown (my_identity, old_successor, trail_id,
3034                                           GDS_ROUTING_SRC_TO_DEST, target_friend);
3035       GDS_NEIGHBOURS_send_notify_new_successor (my_identity, my_new_successor,
3036                                                 new_trail,
3037                                                 new_trail_length,
3038                                                 new_finger_trail_id, target_friend);
3039     }
3040     return GNUNET_OK;
3041   }
3042
3043   GNUNET_assert (NULL != (next_hop =
3044                          GDS_ROUTING_get_next_hop (trail_id, trail_direction)));
3045   target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
3046   GDS_NEIGHBOURS_send_verify_successor_result (destination_peer,
3047                                                vsrm->source_successor,
3048                                                my_new_successor, trail_id,
3049                                                new_trail,
3050                                                new_trail_length,
3051                                                trail_direction, target_friend);
3052   return GNUNET_OK;
3053 }
3054
3055
3056 /*
3057  * Core handle for p2p notify new successor messages.
3058  * @param cls closure
3059  * @param message message
3060  * @param peer peer identity this notification is about
3061  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
3062  */
3063 static int
3064 handle_dht_p2p_notify_new_successor(void *cls, const struct GNUNET_PeerIdentity *peer,
3065                                     const struct GNUNET_MessageHeader *message)
3066 {
3067   struct PeerNotifyNewSuccessorMessage *nsm;
3068   struct GNUNET_PeerIdentity *trail;
3069   struct GNUNET_PeerIdentity source;
3070   struct GNUNET_PeerIdentity destination;
3071   struct FriendInfo *target_friend;
3072   struct GNUNET_HashCode trail_id;
3073   unsigned int my_index;
3074   struct GNUNET_PeerIdentity next_hop;
3075   size_t msize;
3076   uint32_t trail_length;
3077
3078   msize = ntohs (message->size);
3079   if (msize != sizeof (struct PeerNotifyNewSuccessorMessage))
3080   {
3081     GNUNET_break_op (0);
3082     return GNUNET_YES;
3083   }
3084
3085   nsm = (struct PeerNotifyNewSuccessorMessage *) message;
3086   trail_length = ntohl (nsm->trail_length);
3087
3088   if ((msize < sizeof (struct PeerNotifyNewSuccessorMessage) +
3089                trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
3090       (trail_length >
3091        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
3092   {
3093     GNUNET_break_op (0);
3094     return GNUNET_YES;
3095   }
3096
3097   trail = (struct GNUNET_PeerIdentity *) &nsm[1];
3098   source  = nsm->source_peer;
3099   destination = nsm->destination_peer;
3100   trail_id = nsm->trail_id;
3101
3102   if ( 0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &destination))
3103   {
3104     struct GNUNET_HashCode new_trail_id;
3105     struct FingerInfo *my_predecessor;
3106
3107     my_predecessor =
3108             GNUNET_CONTAINER_multihashmap32_get (finger_hashmap,
3109                                                  PREDECESSOR_FINGER_ID);
3110     /* FIXME: get new_trail_id*/
3111
3112     if (GNUNET_YES == is_new_entry_correct_predecessor (my_predecessor,
3113                                                         source, trail,
3114                                                         trail_length))
3115     {
3116
3117       target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap,
3118                                                          peer);
3119       GDS_NEIGHBOURS_send_add_trail (my_identity, source, new_trail_id,
3120                                      trail, trail_length, target_friend);
3121       return GNUNET_OK;
3122     }
3123   }
3124
3125   my_index = search_my_index (trail, trail_length);
3126   if (GNUNET_SYSERR == my_index)
3127   {
3128     GNUNET_break_op (0);
3129     return GNUNET_SYSERR;
3130   }
3131   if (trail_length == my_index)
3132     next_hop = destination;
3133   else
3134     next_hop = trail[my_index + 1];
3135   GNUNET_assert (GNUNET_OK == GDS_ROUTING_add (trail_id, *peer, next_hop));
3136   target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
3137   GDS_NEIGHBOURS_send_notify_new_successor (source, destination, trail,
3138                                             trail_length,
3139                                             trail_id, target_friend);
3140   return GNUNET_OK;
3141 }
3142
3143
3144 /**
3145  * FIXME: Here you should keep the trail id with you.
3146  * Core handler for P2P trail rejection message
3147  * @param cls closure
3148  * @param message message
3149  * @param peer peer identity this notification is about
3150  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
3151  */
3152 static int
3153 handle_dht_p2p_trail_rejection(void *cls, const struct GNUNET_PeerIdentity *peer,
3154                                const struct GNUNET_MessageHeader *message)
3155 {
3156   struct PeerTrailRejectionMessage *trail_rejection;
3157   unsigned int trail_length;
3158   struct GNUNET_PeerIdentity *trail_peer_list;
3159   struct FriendInfo *target_friend;
3160   struct GNUNET_TIME_Relative congestion_timeout;
3161   struct GNUNET_HashCode trail_id;
3162   struct GNUNET_PeerIdentity next_destination;
3163   struct GNUNET_HashCode new_intermediate_trail_id;
3164   struct GNUNET_PeerIdentity next_peer;
3165   struct GNUNET_PeerIdentity source;
3166   struct GNUNET_PeerIdentity *next_hop;
3167   uint64_t ultimate_destination_finger_value;
3168   unsigned int finger_map_index;
3169   size_t msize;
3170
3171   msize = ntohs (message->size);
3172   if (msize != sizeof (struct PeerTrailRejectionMessage))
3173   {
3174     GNUNET_break_op (0);
3175     return GNUNET_YES;
3176   }
3177
3178   trail_rejection = (struct PeerTrailRejectionMessage *) message;
3179   trail_length = ntohl (trail_rejection->trail_length);
3180
3181   if ((msize != sizeof (struct PeerTrailRejectionMessage) +
3182                trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
3183       (trail_length >
3184        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
3185   {
3186     GNUNET_break_op (0);
3187     return GNUNET_YES;
3188   }
3189
3190   trail_peer_list = (struct GNUNET_PeerIdentity *)&trail_rejection[1];
3191   finger_map_index = ntohl (trail_rejection->finger_map_index);
3192   congestion_timeout = trail_rejection->congestion_time;
3193   source = trail_rejection->source_peer;
3194   trail_id = trail_rejection->trail_id;
3195   ultimate_destination_finger_value =
3196   trail_rejection->ultimate_destination_finger_identity_value;
3197
3198   /* First set the congestion time of the friend that sent you this message. */
3199   target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, peer);
3200   target_friend->congestion_timestamp = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(),
3201                                                                  congestion_timeout);
3202
3203   if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &source)))
3204   {
3205     return GNUNET_OK;
3206   }
3207
3208   /* If I am congested then pass this message to peer before me in trail. */
3209   if(GNUNET_YES == GDS_ROUTING_threshold_reached())
3210   {
3211     struct GNUNET_PeerIdentity *new_trail;
3212     unsigned int new_trail_length;
3213
3214     if (trail_length == 1)
3215     {
3216       new_trail = NULL;
3217       new_trail_length = 0;
3218       next_hop = &source;
3219     }
3220     else
3221     {
3222       next_hop = &trail_peer_list[trail_length - 2];
3223       /* Remove myself from the trail. */
3224       new_trail_length = trail_length -1;
3225       new_trail = GNUNET_malloc (new_trail_length * sizeof (struct GNUNET_PeerIdentity));
3226       memcpy (new_trail, trail_peer_list, new_trail_length * sizeof (struct GNUNET_PeerIdentity));
3227     }
3228
3229     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
3230     GDS_NEIGHBOURS_send_trail_rejection (source,
3231                                          ultimate_destination_finger_value,
3232                                          my_identity, finger_map_index,
3233                                          new_trail,new_trail_length,trail_id,
3234                                          target_friend, CONGESTION_TIMEOUT);
3235     return GNUNET_YES;
3236   }
3237
3238   /* Look for next_hop to pass the trail setup message */
3239   next_hop = find_successor (ultimate_destination_finger_value,
3240                              &next_destination,
3241                              &new_intermediate_trail_id,
3242                              finger_map_index);
3243
3244   if (0 == (GNUNET_CRYPTO_cmp_peer_identity (next_hop, &my_identity)))/* This means I am the final destination */
3245   {
3246     if (0 == trail_length)
3247       next_peer = source;
3248     else
3249       next_peer = trail_peer_list[trail_length-1];
3250
3251     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_peer);
3252     GDS_NEIGHBOURS_send_trail_setup_result (source,
3253                                             my_identity,
3254                                             target_friend, trail_length,
3255                                             trail_peer_list,
3256                                             finger_map_index, trail_id);
3257   }
3258   else
3259   {
3260     struct GNUNET_PeerIdentity peer_list[trail_length + 1];
3261
3262     memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
3263     peer_list[trail_length] = my_identity;
3264
3265     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
3266     GDS_NEIGHBOURS_send_trail_setup (source,
3267                                      ultimate_destination_finger_value,
3268                                      next_destination,
3269                                      target_friend, trail_length + 1, peer_list,
3270                                      finger_map_index, trail_id,
3271                                      &new_intermediate_trail_id);
3272   }
3273   return GNUNET_OK;
3274 }
3275
3276
3277 /*
3278  * Core handle for p2p trail tear down messages.
3279  * @param cls closure
3280  * @param message message
3281  * @param peer peer identity this notification is about
3282  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
3283  */
3284 static int
3285 handle_dht_p2p_trail_compression (void *cls, const struct GNUNET_PeerIdentity *peer,
3286                                const struct GNUNET_MessageHeader *message)
3287 {
3288   struct PeerTrailCompressionMessage *trail_compression;
3289   struct GNUNET_PeerIdentity *next_hop;
3290   struct GNUNET_HashCode trail_id;
3291   struct FriendInfo *target_friend;
3292   size_t msize;
3293
3294   msize = ntohs (message->size);
3295   if (msize != sizeof (struct PeerTrailCompressionMessage))
3296   {
3297     GNUNET_break_op (0);
3298     return GNUNET_OK;
3299   }
3300
3301   trail_compression = (struct PeerTrailCompressionMessage *) message;
3302   trail_id = trail_compression->trail_id;
3303
3304   if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_compression->new_first_friend),
3305                                              &my_identity)))
3306   {
3307      if(0 != (GNUNET_CRYPTO_cmp_peer_identity (&(trail_compression->destination_peer),
3308                                                &my_identity)))
3309      {
3310        GDS_ROUTING_update_trail_prev_hop (trail_id,
3311                                           trail_compression->source_peer);
3312      }
3313      return GNUNET_OK;
3314   }
3315
3316   next_hop = GDS_ROUTING_get_next_hop (trail_id, GDS_ROUTING_SRC_TO_DEST);
3317   if (NULL == next_hop)
3318   {
3319     GNUNET_break (0); /*FIXME: How to handle this case.  */
3320     return GNUNET_OK;
3321   }
3322   GNUNET_assert (GNUNET_YES == GDS_ROUTING_remove_trail (trail_id));
3323   target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
3324   GDS_NEIGHBOURS_send_trail_compression (trail_compression->source_peer,
3325                                          trail_compression->destination_peer,
3326                                          trail_id,
3327                                          trail_compression->new_first_friend,
3328                                          target_friend);
3329   return GNUNET_OK;
3330 }
3331
3332
3333 /**
3334  * Core handler for trail teardown message.
3335  * @param cls closure
3336  * @param message message
3337  * @param peer peer identity this notification is about
3338  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
3339  */
3340 static int
3341 handle_dht_p2p_trail_teardown (void *cls, const struct GNUNET_PeerIdentity *peer,
3342                                const struct GNUNET_MessageHeader *message)
3343 {
3344   struct PeerTrailTearDownMessage *trail_teardown;
3345   struct GNUNET_HashCode trail_id;
3346   enum GDS_ROUTING_trail_direction trail_direction;
3347   size_t msize;
3348
3349   msize = ntohs (message->size);
3350   if (msize != sizeof (struct PeerTrailTearDownMessage))
3351   {
3352     GNUNET_break_op (0);
3353     return GNUNET_OK;
3354   }
3355
3356   trail_teardown = (struct PeerTrailTearDownMessage *) message;
3357   trail_direction = ntohl (trail_teardown->trail_direction);
3358   trail_id = trail_teardown->TRAIL_ID;
3359
3360   if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity,
3361                                             &trail_teardown->destination_peer))
3362   {
3363     struct GNUNET_PeerIdentity *next_hop;
3364     struct FriendInfo *target_friend;
3365
3366     next_hop = GDS_ROUTING_get_next_hop (trail_id, trail_direction);
3367     if (NULL == next_hop)
3368     {
3369       GNUNET_break (0);
3370       return GNUNET_SYSERR;
3371     }
3372
3373     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap,
3374                                                        next_hop);
3375     GNUNET_assert (GNUNET_YES == GDS_ROUTING_remove_trail (trail_id));
3376     GDS_NEIGHBOURS_send_trail_teardown (trail_teardown->source_peer,
3377                                         trail_teardown->destination_peer,
3378                                         trail_id, trail_direction,
3379                                         target_friend);
3380   }
3381   return GNUNET_OK;
3382 }
3383
3384
3385 /**
3386  * Fixme: this function is called only in case in notify new successor, the new
3387  * successor wants to add the source of the peer as its predecessor. Identify
3388  * if there is any other use case where it is required and if yes then adapt the
3389  * code for it.
3390  * Core handle for p2p add trail message.
3391  * @param cls closure
3392  * @param message message
3393  * @param peer peer identity this notification is about
3394  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
3395  */
3396 static int
3397 handle_dht_p2p_add_trail (void *cls, const struct GNUNET_PeerIdentity *peer,
3398                           const struct GNUNET_MessageHeader *message)
3399 {
3400   struct PeerAddTrailMessage *add_trail;
3401   struct GNUNET_PeerIdentity *trail;
3402   struct GNUNET_HashCode trail_id;
3403   struct GNUNET_PeerIdentity destination_peer;
3404   struct GNUNET_PeerIdentity source_peer;
3405   struct GNUNET_PeerIdentity next_hop;
3406   unsigned int trail_length;
3407   unsigned int my_index;
3408   size_t msize;
3409
3410   msize = ntohs (message->size);
3411   if (msize != sizeof (struct PeerAddTrailMessage))
3412   {
3413     GNUNET_break_op (0);
3414     return GNUNET_OK;
3415   }
3416
3417   add_trail = (struct PeerAddTrailMessage *) message;
3418   trail_length = ntohl (add_trail->trail_length);
3419
3420   if ((msize < sizeof (struct PeerAddTrailMessage) +
3421                trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
3422       (trail_length >
3423        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
3424   {
3425     GNUNET_break_op (0);
3426     return GNUNET_OK;
3427   }
3428
3429   trail = (struct GNUNET_PeerIdentity *)&add_trail[1];
3430   destination_peer = add_trail->destination_peer;
3431   source_peer = add_trail->source_peer;
3432   trail_id = add_trail->trail_id;
3433
3434   if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity,
3435                                             &destination_peer))
3436   {
3437     struct FriendInfo *target_friend;
3438
3439     my_index = search_my_index (trail, trail_length);
3440     if (GNUNET_SYSERR == my_index)
3441     {
3442       GNUNET_break_op (0);
3443       return GNUNET_SYSERR;
3444     }
3445
3446     if (0 == my_index)
3447       next_hop = source_peer;
3448     else
3449       next_hop = trail[trail_length - 1];
3450
3451     GNUNET_assert (GNUNET_OK == GDS_ROUTING_add (trail_id, next_hop, *peer));
3452     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
3453     GDS_NEIGHBOURS_send_add_trail (source_peer, destination_peer, trail_id,
3454                                    trail, trail_length, target_friend);
3455   }
3456   return GNUNET_OK;
3457 }
3458
3459
3460 /**
3461  *FIXME; call send_trail_teardown_message on all the trails of the finger that
3462  * you remove. Also you don't need to decerement friend trail count as that
3463  * friend is removed. But you can not send trail teardown message as the friend
3464  * is disconnected. then you don't have any next_hop. and in case there are
3465  * multiple trails. and friend is the first trail then you remove only the trail.
3466  * Iterate over finger_hashmap, and remove entries if finger is the disconnected
3467  * peer or if disconnected peer is the first friend in the trail to reach the
3468  * finger.
3469  * @param cls closure
3470  * @param key current public key
3471  * @param value value in the hash map
3472  * @return #GNUNET_YES if we should continue to
3473  *         iterate,
3474  *         #GNUNET_NO if not.
3475  */
3476 static int
3477 remove_matching_finger (void *cls,
3478                         uint32_t key,
3479                         void *value)
3480 {
3481   struct FingerInfo *remove_finger = value;
3482   const struct GNUNET_PeerIdentity *disconnected_peer = cls;
3483   struct TrailList *trail_list;
3484   int i;
3485
3486   if (0 == GNUNET_CRYPTO_cmp_peer_identity (&remove_finger->finger_identity,
3487                                             disconnected_peer))
3488   {
3489     GNUNET_assert (GNUNET_YES ==
3490                    GNUNET_CONTAINER_multihashmap32_remove (finger_hashmap,
3491                                                          key,
3492                                                          remove_finger));
3493     free_finger (remove_finger);
3494     return GNUNET_YES;
3495   }
3496
3497   for (i = 0; i< remove_finger->trails_count; i++)
3498   {
3499     trail_list = &remove_finger->trail_list[i];
3500     if (0 == GNUNET_CRYPTO_cmp_peer_identity (&trail_list->trail_head->peer,
3501                                                 disconnected_peer))
3502     {
3503       GNUNET_assert (GNUNET_YES ==
3504                      GNUNET_CONTAINER_multihashmap32_remove (finger_hashmap,
3505                                                            key,
3506                                                            remove_finger));
3507        free_finger (remove_finger);
3508     }
3509   }
3510
3511   return GNUNET_YES;
3512 }
3513
3514
3515 /**
3516  * Method called whenever a peer disconnects.
3517  *
3518  * @param cls closure
3519  * @param peer peer identity this notification is about
3520  */
3521 static void
3522 handle_core_disconnect (void *cls,
3523                                           const struct GNUNET_PeerIdentity *peer)
3524 {
3525   struct FriendInfo *remove_friend;
3526
3527   if (0 == memcmp (&my_identity, peer, sizeof (struct GNUNET_PeerIdentity)))
3528     return;
3529
3530   remove_friend =
3531       GNUNET_CONTAINER_multipeermap_get (friend_peermap, peer);
3532
3533   if (NULL == remove_friend)
3534   {
3535     GNUNET_break (0);
3536     return;
3537   }
3538
3539   GNUNET_assert (GNUNET_SYSERR !=
3540                  GNUNET_CONTAINER_multihashmap32_iterate (finger_hashmap,
3541                                                           &remove_matching_finger,
3542                                                           (void *)peer));
3543   GDS_ROUTING_remove_trail_by_peer (peer);
3544   GNUNET_assert (GNUNET_YES ==
3545                  GNUNET_CONTAINER_multipeermap_remove (friend_peermap,
3546                                                        peer,
3547                                                        remove_friend));
3548
3549   if (0 != GNUNET_CONTAINER_multipeermap_size (friend_peermap))
3550     return;
3551
3552   if (GNUNET_SCHEDULER_NO_TASK != find_finger_trail_task)
3553   {
3554       GNUNET_SCHEDULER_cancel (find_finger_trail_task);
3555       find_finger_trail_task = GNUNET_SCHEDULER_NO_TASK;
3556   }
3557   else
3558     GNUNET_break (0);
3559 }
3560
3561
3562 /**
3563  * Method called whenever a peer connects.
3564  *
3565  * @param cls closure
3566  * @param peer_identity peer identity this notification is about
3567  */
3568 static void
3569 handle_core_connect (void *cls, const struct GNUNET_PeerIdentity *peer_identity)
3570 {
3571   struct FriendInfo *friend;
3572
3573   /* Check for connect to self message */
3574   if (0 == memcmp (&my_identity, peer_identity, sizeof (struct GNUNET_PeerIdentity)))
3575     return;
3576
3577   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected to %s\n", GNUNET_i2s (peer_identity));
3578
3579   /* If peer already exists in our friend_peermap, then exit. */
3580   if (GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains (friend_peermap, peer_identity))
3581   {
3582     GNUNET_break (0);
3583     return;
3584   }
3585
3586   GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# peers connected"), 1,
3587                             GNUNET_NO);
3588
3589   friend = GNUNET_new (struct FriendInfo);
3590   friend->id = *peer_identity;
3591
3592   GNUNET_assert (GNUNET_OK ==
3593                  GNUNET_CONTAINER_multipeermap_put (friend_peermap,
3594                                                     peer_identity, friend,
3595                                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
3596
3597   /* got a first connection, good time to start with FIND FINGER TRAIL requests... */
3598   if (GNUNET_SCHEDULER_NO_TASK == find_finger_trail_task)
3599     find_finger_trail_task = GNUNET_SCHEDULER_add_now (&send_find_finger_trail_message, NULL);
3600 }
3601
3602
3603 /**
3604  * To be called on core init/fail.
3605  *
3606  * @param cls service closure
3607  * @param identity the public identity of this peer
3608  */
3609 static void
3610 core_init (void *cls,
3611            const struct GNUNET_PeerIdentity *identity)
3612 {
3613   my_identity = *identity;
3614 }
3615
3616
3617 /**
3618  * Initialize neighbours subsystem.
3619  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
3620  */
3621 int
3622 GDS_NEIGHBOURS_init (void)
3623 {
3624   static struct GNUNET_CORE_MessageHandler core_handlers[] = {
3625     {&handle_dht_p2p_put, GNUNET_MESSAGE_TYPE_DHT_P2P_PUT, 0},
3626     {&handle_dht_p2p_get, GNUNET_MESSAGE_TYPE_DHT_P2P_GET, 0},
3627     {&handle_dht_p2p_get_result, GNUNET_MESSAGE_TYPE_DHT_P2P_GET_RESULT, 0},
3628     {&handle_dht_p2p_trail_setup, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP, 0},
3629     {&handle_dht_p2p_trail_setup_result, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP_RESULT, 0},
3630     {&handle_dht_p2p_verify_successor, GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR, 0},
3631     {&handle_dht_p2p_verify_successor_result, GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR_RESULT, 0},
3632     {&handle_dht_p2p_notify_new_successor, GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_NEW_SUCCESSOR, 0},
3633     {&handle_dht_p2p_trail_rejection, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_REJECTION, 0},
3634     {&handle_dht_p2p_trail_compression, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_COMPRESSION, 0},
3635     {&handle_dht_p2p_trail_teardown, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_TEARDOWN, 0},
3636     {&handle_dht_p2p_add_trail, GNUNET_MESSAGE_TYPE_DHT_P2P_ADD_TRAIL, 0},
3637     {NULL, 0, 0}
3638   };
3639
3640   core_api =
3641     GNUNET_CORE_connect (GDS_cfg, NULL, &core_init, &handle_core_connect,
3642                          &handle_core_disconnect, NULL, GNUNET_NO, NULL,
3643                          GNUNET_NO, core_handlers);
3644   if (NULL == core_api)
3645     return GNUNET_SYSERR;
3646
3647   friend_peermap = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_NO);
3648   finger_hashmap = GNUNET_CONTAINER_multihashmap32_create (MAX_FINGERS * 4/3);
3649
3650   return GNUNET_OK;
3651 }
3652
3653 /**
3654  * Shutdown neighbours subsystem.
3655  */
3656 void
3657 GDS_NEIGHBOURS_done (void)
3658 {
3659   if (NULL == core_api)
3660     return;
3661
3662   GNUNET_CORE_disconnect (core_api);
3663   core_api = NULL;
3664
3665   GNUNET_assert (0 == GNUNET_CONTAINER_multipeermap_size (friend_peermap));
3666   GNUNET_CONTAINER_multipeermap_destroy (friend_peermap);
3667   friend_peermap = NULL;
3668
3669   GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap32_size (finger_hashmap));
3670   GNUNET_CONTAINER_multihashmap32_destroy (finger_hashmap);
3671   finger_hashmap = NULL;
3672
3673   if (GNUNET_SCHEDULER_NO_TASK != find_finger_trail_task)
3674   {
3675     GNUNET_break (0);
3676     GNUNET_SCHEDULER_cancel (find_finger_trail_task);
3677     find_finger_trail_task = GNUNET_SCHEDULER_NO_TASK;
3678   }
3679 }
3680
3681
3682 /**
3683  * Get my identity
3684  *
3685  * @return my identity
3686  */
3687 struct GNUNET_PeerIdentity
3688 GDS_NEIGHBOURS_get_my_id (void)
3689 {
3690   return my_identity;
3691 }