Using trail id
[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  * Finger map index for predecessor entry in finger peermap. 
84  */
85 #define PREDECESSOR_FINGER_ID 64
86
87 /**
88  * Maximum number of trails allowed to go through a friend.
89  */
90 #define TRAILS_THROUGH_FRIEND_THRESHOLD 64
91
92 GNUNET_NETWORK_STRUCT_BEGIN
93
94 /**
95  * P2P Trail setup message
96  */
97 struct PeerTrailSetupMessage
98 {
99   /**
100    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP
101    */
102   struct GNUNET_MessageHeader header;
103   
104   /**
105    * Peer closest to this value will be our finger. 
106    */
107   uint64_t ultimate_destination_finger;
108
109   /**
110    * Source peer which wants to setup the trail to one of its finger. 
111    */
112   struct GNUNET_PeerIdentity source_peer;
113   
114   /**
115    * Peer to which this packet is forwarded.
116    */
117   struct GNUNET_PeerIdentity next_destination;
118   
119   /**
120    * Index into finger peer map, in Network Byte Order. 
121    */
122   uint32_t finger_map_index;
123   
124   /**
125    * Number of entries in trail list, in Network Byte Order.
126    */
127   uint32_t trail_length GNUNET_PACKED;
128   
129   /**
130    * Trail id of any intermediate trail we may encounter while doing trail setup.
131    */
132   struct GNUNET_HashCode intermediate_trail_id;
133   
134   /**
135    * Trail id for trail which we are trying to setup. 
136    */
137   struct GNUNET_HashCode new_trail_id;
138   
139   /* Trail formed in the process. */
140 };
141
142 /**
143   * P2P Trail Setup Result message
144  */
145 struct PeerTrailSetupResultMessage
146 {
147   
148   /**
149    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP_RESULT
150    */
151   struct GNUNET_MessageHeader header;
152   
153   /**
154    * Finger to which we have found the path. 
155    */
156   struct GNUNET_PeerIdentity finger_identity;
157
158   /**
159    * Peer which was looking for the trail to finger. 
160    */
161   struct GNUNET_PeerIdentity destination_peer;
162   
163   /**
164    * Index into finger peer map in NBO.
165    */
166   uint32_t finger_map_index;
167   
168   /**
169    * Number of entries in trail list in NBO.
170    */
171   uint32_t trail_length GNUNET_PACKED;
172   
173   /**
174    * Identifier of the trail. 
175    */
176   struct GNUNET_HashCode trail_id;
177   /* Trail from destination_peer to finger_identity */
178   
179 };
180
181 struct PeerVerifySuccessorMessage
182 {
183   /**
184    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR
185    */
186   struct GNUNET_MessageHeader header;
187   
188   /**
189    * Source peer which wants to verify its successor. 
190    */
191   struct GNUNET_PeerIdentity source_peer;
192   
193   /**
194    * My current successor.
195    */
196   struct GNUNET_PeerIdentity successor;
197   
198   /**
199    * Identifier of trail to reach from source_peer to successor.
200    */
201   struct GNUNET_HashCode trail_id;
202 };
203
204 struct PeerVerifySuccessorResultMessage
205 {
206   /**
207    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR_RESULT
208    */
209   struct GNUNET_MessageHeader header;
210   
211   /**
212    * Destination peer which sent the request to verify its successor. 
213    */
214   struct GNUNET_PeerIdentity destination_peer;
215   
216   /**
217    * Successor to which PeerVerifySuccessorMessage was sent.
218    */
219   struct GNUNET_PeerIdentity source_successor;
220   
221   /**
222    * source_successor's predecessor
223    */
224   struct GNUNET_PeerIdentity my_predecessor;
225   
226   /**
227    * Trail identifier of trail from my_predecessor to source_successor. 
228    */
229   struct GNUNET_HashCode trail_id;
230   
231   enum GDS_ROUTING_trail_direction trail_direction;
232   /**
233    * Total number of peers in trail from source_successor to my_predecessor
234    * if my_predecessor is not same as destination_peer. 
235    */
236   uint32_t trail_length; 
237   
238   /* Trail from source_successor to my_predecessor where 
239    * my_predecessor != destination_peer*/
240 };
241
242 struct PeerNotifyNewSuccessorMessage
243 {
244   /**
245    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_NEW_SUCCESSOR
246    */
247   struct GNUNET_MessageHeader header;
248   
249   /**
250    * Source peer which wants to notify its new successor. 
251    */
252   struct GNUNET_PeerIdentity source_peer;
253   
254   /**
255    * New successor identity.
256    */
257   struct GNUNET_PeerIdentity destination_peer;
258   
259   unsigned int trail_length;
260   
261   struct GNUNET_HashCode trail_id;
262   
263   /* Trail. */
264 };
265
266 /**
267  * Trail compressiong message. 
268  */
269 struct PeerTrailCompressionMessage
270 {
271   /**
272    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_COMPRESSION
273    */
274   struct GNUNET_MessageHeader header;
275   
276   /**
277    * Source peer of this trail.  
278    */
279   struct GNUNET_PeerIdentity source_peer;
280   
281   /**
282    * Destination of this trail. 
283    */
284   struct GNUNET_PeerIdentity destination_peer;
285   
286   /**
287    * Trail from source_peer to destination_peer compressed such that 
288    * new_first_friend is the first hop in the trail from source to 
289    * destination. 
290    */
291   struct GNUNET_PeerIdentity new_first_friend;
292   
293   /**
294    * Unique identifier of trail. 
295    */
296   struct GNUNET_HashCode trail_id;
297 };
298
299 /**
300  * Trail Tear Down message. 
301  */
302 struct PeerTrailTearDownMessage
303 {
304   /**
305    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_TEARDOWN
306    */
307   struct GNUNET_MessageHeader header;
308 };
309
310 /**
311  * Trail Rejection Message.
312  */
313 struct PeerTrailRejectionMessage
314 {
315   /**
316    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_REJECTION
317    */
318   struct GNUNET_MessageHeader header;
319   
320   /**
321    * Source peer which wants to set up the trail. 
322    */
323   struct GNUNET_PeerIdentity source_peer;
324   
325   /**
326    * Peer which sent trail rejection message. 
327    */
328   struct GNUNET_PeerIdentity congested_peer;
329   
330   /**
331    * Peer identity which will be successor to this value will be finger of
332    * source_peer. 
333    */
334   uint64_t ultimate_destination_finger_identity_value;
335   
336   /**
337    * Index in finger peer map of source peer.
338    */
339   uint32_t finger_map_index;
340   
341   /**
342    * Total number of peers in the trail.
343    */
344   uint32_t trail_length;
345   
346   /**
347    * Identifier for the trail source peer is trying to setup. 
348    */
349   struct GNUNET_HashCode trail_id;
350   /**
351    * Relative time for which congested_peer will remain congested. 
352    */
353   struct GNUNET_TIME_Relative congestion_time;
354   
355   /* Trail_list from source_peer to peer which sent the message for trail setup
356    * to congested peer.*/
357 };
358
359 GNUNET_NETWORK_STRUCT_END        
360         
361 /**
362  * Linked list of messages to send to a particular other peer.
363  */
364 struct P2PPendingMessage
365 {
366   /**
367    * Pointer to next item in the list
368    */
369   struct P2PPendingMessage *next;
370
371   /**
372    * Pointer to previous item in the list
373    */
374   struct P2PPendingMessage *prev;
375
376   /**
377    * Message importance level.  FIXME: used? useful?
378    */
379   unsigned int importance;
380   
381   /**
382    * When does this message time out?
383    */
384   struct GNUNET_TIME_Absolute timeout;
385   
386   /**
387    * Actual message to be sent, allocated at the end of the struct:
388    * // msg = (cast) &pm[1];
389    * // memcpy (&pm[1], data, len);
390    */
391   const struct GNUNET_MessageHeader *msg;
392
393 };
394
395         
396 /** 
397  *  Entry in friend_peermap.
398  */
399 struct FriendInfo
400 {
401   /**
402    * Friend Identity 
403    */
404   struct GNUNET_PeerIdentity id;
405
406   /**
407    * Number of trails for which this friend is the first hop. 
408    */
409   unsigned int trails_count;
410   
411   /**
412    * Count of outstanding messages for this friend.
413    */
414   unsigned int pending_count;
415   
416   /**
417    * In case not 0, then amount of time for which this friend is congested. 
418    */
419   struct GNUNET_TIME_Absolute congestion_duration;
420   
421   /**
422    * Head of pending messages to be sent to this friend.
423    */
424   struct P2PPendingMessage *head;
425
426   /**
427    * Tail of pending messages to be sent to this friend.
428    */
429   struct P2PPendingMessage *tail;
430  
431   /**
432    * Core handle for sending messages to this friend.
433    */
434   struct GNUNET_CORE_TransmitHandle *th;
435
436 };
437
438 /**
439  * An individual trail to reach to a finger.
440  */
441 struct Trail
442 {
443   /**
444     * Pointer to next item in the list
445     */
446   struct Trail *next;
447   
448   /**
449     * Pointer to prev item in the list
450     */
451   struct Trail *prev;
452   
453   /**
454    * An element in this trail. 
455    */
456   struct GNUNET_PeerIdentity peer;
457 };
458
459 /**
460  * List of all trails to reach a particular finger.
461  */
462 struct TrailList
463 {
464   /**
465    * Head of trail.
466    */
467   struct Trail *trail_head;
468   
469   /**
470    * Tail of trail.
471    */
472   struct Trail *trail_tail;
473   
474   /**
475    * Unique identifier of this trail. 
476    */
477   struct GNUNET_HashCode trail_id;
478   
479   /**
480    * Length of trail pointed 
481    */
482   unsigned int trail_length;
483   
484   /**
485    * Number of trails that the first friend of this trail is a part of. 
486    */
487   unsigned int first_friend_trail_count;
488 };
489
490
491 /**
492  * An entry in finger_hashmap. 
493  */
494 struct FingerInfo
495 {
496   /**
497    * Finger identity.
498    */
499   struct GNUNET_PeerIdentity finger_identity;
500   
501   /**
502    * Index in finger peer map
503    */
504   unsigned int finger_map_index;  
505   
506   /**
507    * Number of trails setup so far for this finger. 
508    */
509   unsigned int trails_count;
510   
511   /**
512    * Array of trails. 
513    */
514   struct TrailList trail_list[MAXIMUM_TRAILS_PER_FINGER];
515 };
516
517
518 /**
519  * Task that sends FIND FINGER TRAIL requests. This task is started when we have
520  * get our first friend. 
521  */
522 static GNUNET_SCHEDULER_TaskIdentifier find_finger_trail_task;
523
524 /**
525  * Identity of this peer.
526  */
527 static struct GNUNET_PeerIdentity my_identity;
528
529 /**
530  * Peer map of all the friends of a peer
531  */
532 static struct GNUNET_CONTAINER_MultiPeerMap *friend_peermap;
533
534 /**
535  * Hash map of all the fingers of a peer
536  */
537 static struct GNUNET_CONTAINER_MultiHashMap32 *finger_hashmap;
538
539 /**
540  * Handle to CORE.
541  */
542 static struct GNUNET_CORE_Handle *core_api;
543
544 /**
545  * The current finger index that we have want to find trail to. We start the 
546  * search with value = 0, i.e. successor peer and then go to PREDCESSOR_FINGER_ID
547  * and decrement it. For any index 63 <= index < 0, if finger is same as successor,
548  * we reset this index to 0.
549  */
550 static unsigned int current_search_finger_index;
551
552
553 /**
554  * Called when core is ready to send a message we asked for
555  * out to the destination.
556  *
557  * @param cls the 'struct FriendInfo' of the target friend
558  * @param size number of bytes available in buf
559  * @param buf where the callee should write the message
560  * @return number of bytes written to buf
561  */
562 static size_t
563 core_transmit_notify (void *cls, size_t size, void *buf)
564 {
565   struct FriendInfo *peer = cls;
566   char *cbuf = buf;
567   struct P2PPendingMessage *pending;
568   size_t off;
569   size_t msize;
570   
571   peer->th = NULL;
572   while ((NULL != (pending = peer->head)) &&
573          (0 == GNUNET_TIME_absolute_get_remaining (pending->timeout).rel_value_us))
574   {
575     peer->pending_count--;
576     GNUNET_CONTAINER_DLL_remove (peer->head, peer->tail, pending);  
577     GNUNET_free (pending);
578   }
579   if (NULL == pending)
580   {
581     /* no messages pending */
582     return 0;
583   }
584   if (NULL == buf)
585   {
586     peer->th =
587         GNUNET_CORE_notify_transmit_ready (core_api, GNUNET_NO,
588                                            GNUNET_CORE_PRIO_BEST_EFFORT,
589                                            GNUNET_TIME_absolute_get_remaining
590                                            (pending->timeout), &peer->id,
591                                            ntohs (pending->msg->size),
592                                            &core_transmit_notify, peer);
593     GNUNET_break (NULL != peer->th);
594     return 0;
595   }
596   off = 0;
597   while ((NULL != (pending = peer->head)) &&
598          (size - off >= (msize = ntohs (pending->msg->size))))
599   {
600     GNUNET_STATISTICS_update (GDS_stats,
601                               gettext_noop
602                               ("# Bytes transmitted to other peers"), msize,
603                               GNUNET_NO);
604     memcpy (&cbuf[off], pending->msg, msize);
605     off += msize;
606     peer->pending_count--;
607     GNUNET_CONTAINER_DLL_remove (peer->head, peer->tail, pending);
608     GNUNET_free (pending);
609   }
610   if (peer->head != NULL)
611   {
612     peer->th =
613         GNUNET_CORE_notify_transmit_ready (core_api, GNUNET_NO,
614                                            GNUNET_CORE_PRIO_BEST_EFFORT,
615                                            GNUNET_TIME_absolute_get_remaining
616                                            (pending->timeout), &peer->id, msize,
617                                            &core_transmit_notify, peer);
618     GNUNET_break (NULL != peer->th);
619   }
620  
621   return off;
622 }
623
624
625 /**
626  * FIXME: assertion fails at the end of this function. also in core_api.c at 1299.
627  * Transmit all messages in the friend's message queue.
628  *
629  * @param peer message queue to process
630  */
631 static void
632 process_friend_queue (struct FriendInfo *peer)
633 {
634   struct P2PPendingMessage *pending;
635   
636   if (NULL == (pending = peer->head))
637     return;
638   if (NULL != peer->th)
639     return;
640   
641   GNUNET_STATISTICS_update (GDS_stats,
642                             gettext_noop
643                             ("# Bytes of bandwidth requested from core"),
644                             ntohs (pending->msg->size), GNUNET_NO);
645   
646   peer->th =
647       GNUNET_CORE_notify_transmit_ready (core_api, GNUNET_NO,
648                                          pending->importance,
649                                          GNUNET_TIME_absolute_get_remaining
650                                          (pending->timeout), &peer->id,
651                                          ntohs (pending->msg->size),
652                                          &core_transmit_notify, peer);
653   GNUNET_break (NULL != peer->th);
654 }
655
656
657 /**
658  * Construct a trail setup message and forward it to target_friend
659  * @param source_peer Source peer which wants to setup the trail
660  * @param ultimate_destination_finger Peer identity closest to this value will 
661  *                                    be finger to @a source_peer
662  * @param next_destination Peer which should get the packet. I can be same as
663  *                         target_friend or different. 
664  * @param target_friend Friend to which message is forwarded now. 
665  * @param trail_length Total number of peers in trail setup so far.
666  * @param trail_peer_list Trail setup so far
667  * @param finger_map_index Index in finger map for which we are looking for finger.
668  * @param trail_id Unique identifier for the trail we are trying to setup.
669  * @param intermediate_trail_id Trail id of any intermediate trail we may have to
670  *                              traverse during trail setup. If not used then set to
671  *                              0. 
672  */
673 void
674 GDS_NEIGHBOURS_send_trail_setup (const struct GNUNET_PeerIdentity source_peer,
675                                  uint64_t ultimate_destination_finger,
676                                  struct GNUNET_PeerIdentity next_destination,
677                                  struct FriendInfo *target_friend,
678                                  unsigned int trail_length,
679                                  const struct GNUNET_PeerIdentity *trail_peer_list,
680                                  unsigned int finger_map_index,
681                                  struct GNUNET_HashCode new_trail_id, 
682                                  struct GNUNET_HashCode intermediate_trail_id)
683 {
684   struct P2PPendingMessage *pending;
685   struct PeerTrailSetupMessage *tsm;
686   struct GNUNET_PeerIdentity *peer_list;
687   size_t msize;
688   
689   msize = sizeof (struct PeerTrailSetupMessage) + 
690           (trail_length * sizeof (struct GNUNET_PeerIdentity));
691   
692   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
693   {
694     GNUNET_break (0);
695     return;
696   }
697   
698   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
699   {  
700     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
701                                 1, GNUNET_NO);
702   }
703   
704   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
705   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
706   tsm = (struct PeerTrailSetupMessage *) &pending[1]; 
707   pending->msg = &tsm->header;
708   tsm->header.size = htons (msize);
709   tsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP);
710   tsm->ultimate_destination_finger = GNUNET_htonll (ultimate_destination_finger);
711   tsm->source_peer = source_peer;
712   tsm->next_destination = next_destination;
713   tsm->trail_length = htonl (trail_length); 
714   tsm->finger_map_index = htonl (finger_map_index);
715   tsm->new_trail_id = new_trail_id;
716   tsm->intermediate_trail_id = intermediate_trail_id;
717   if (trail_length > 0)
718   {
719     peer_list = (struct GNUNET_PeerIdentity *) &tsm[1];
720     memcpy (peer_list, trail_peer_list, trail_length * sizeof(struct GNUNET_PeerIdentity));
721   }
722
723   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
724   target_friend->pending_count++;
725   process_friend_queue (target_friend);
726 }
727
728
729 /**
730  * Construct a trail setup result message and forward it to target friend.
731  * @param destination_peer 
732  * @param source_finger
733  * @param target_friend
734  * @param trail_length
735  * @param trail_peer_list
736  * @param finger_map_index
737  * @param trail_id
738  */
739 void
740 GDS_NEIGHBOURS_send_trail_setup_result (struct GNUNET_PeerIdentity destination_peer,
741                                         struct GNUNET_PeerIdentity source_finger,
742                                         struct FriendInfo *target_friend,
743                                         unsigned int trail_length,
744                                         const struct GNUNET_PeerIdentity *trail_peer_list,
745                                         unsigned int finger_map_index,
746                                         struct GNUNET_HashCode trail_id)
747 {
748   struct P2PPendingMessage *pending;
749   struct PeerTrailSetupResultMessage *tsrm;
750   struct GNUNET_PeerIdentity *peer_list;
751   size_t msize;
752   
753   msize = sizeof (struct PeerTrailSetupResultMessage) + 
754           (trail_length * sizeof (struct GNUNET_PeerIdentity));
755   
756   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
757   {
758     GNUNET_break (0);
759     return;
760   }
761   
762   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
763   {  
764     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
765                                 1, GNUNET_NO);
766   }
767   
768   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
769   pending->importance = 0;    
770   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
771   tsrm = (struct PeerTrailSetupResultMessage *) &pending[1]; 
772   pending->msg = &tsrm->header;
773   tsrm->header.size = htons (msize);
774   tsrm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP_RESULT);
775   tsrm->destination_peer = destination_peer;
776   tsrm->finger_identity = source_finger;
777   tsrm->trail_length = htonl (trail_length);
778   tsrm->finger_map_index = htonl (finger_map_index);
779   tsrm->trail_id = trail_id;
780   
781   peer_list = (struct GNUNET_PeerIdentity *) &tsrm[1];
782   if (trail_length > 0)
783   {
784     memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
785   }
786   /* Send the message to chosen friend. */
787   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
788   target_friend->pending_count++;
789   process_friend_queue (target_friend);
790 }
791
792
793 /**
794  * Send trail rejection message to next_hop
795  * @param source_peer Source peer which is trying to setup the trail.
796  * @param finger_identity Peer closest to this value will be @a source_peer's finger 
797  * @param congested_peer Peer which sent this message as it is congested.
798  * @param next_hop Peer to which we are forwarding this message. 
799  * @param finger_map_index Index in finger peermap for which we are searching for finger.
800  * @param trail_peer_list Trails seen so far in trail setup before getting rejected
801  *                        by congested_peer
802  * @param trail_length Total number of peers in trail_peer_list
803  * @param trail_id Unique identifier of this trail.
804  * @param congestion_timeout Duration given by congested peer as an estimate of 
805  *                           how long it may remain congested.  
806  */
807 void
808 GDS_NEIGHBOURS_send_trail_rejection (struct GNUNET_PeerIdentity source_peer,
809                                      uint64_t finger_identity,
810                                      struct GNUNET_PeerIdentity congested_peer,
811                                      unsigned int finger_map_index,
812                                      struct GNUNET_PeerIdentity *trail_peer_list,
813                                      unsigned int trail_length, 
814                                      struct GNUNET_HashCode trail_id,
815                                      struct FriendInfo *target_friend,
816                                      const struct GNUNET_TIME_Relative congestion_timeout)
817 {
818   struct PeerTrailRejectionMessage *trm;
819   struct P2PPendingMessage *pending;
820   struct GNUNET_PeerIdentity *peer_list;
821   size_t msize;
822   
823   msize = sizeof (struct PeerTrailRejectionMessage) + 
824           (trail_length * sizeof (struct GNUNET_PeerIdentity));
825   
826   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
827   {
828     GNUNET_break (0);
829     return;
830   }
831   
832   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
833   {  
834     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
835                                 1, GNUNET_NO);
836   }
837   
838   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
839   pending->importance = 0;    
840   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
841   trm = (struct PeerTrailRejectionMessage *)&pending[1];
842   pending->msg = &trm->header;
843   trm->header.size = htons (msize);
844   trm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_REJECTION);
845   trm->source_peer = source_peer;
846   trm->congested_peer = congested_peer;
847   trm->congestion_time = congestion_timeout;
848   trm->finger_map_index = htonl (finger_map_index);
849   trm->trail_id = trail_id;
850   
851   peer_list = (struct GNUNET_PeerIdentity *) &trm[1];
852   if (trail_length > 0)
853   {
854     memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
855   }
856   /* Send the message to chosen friend. */
857   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
858   target_friend->pending_count++;
859   process_friend_queue (target_friend);
860 }
861
862
863 /**
864  * Construct a verify successor message and forward it to target_friend. 
865  * @param source_peer Peer which wants to verify its successor. 
866  * @param successor Peer which is @a source_peer's current successor. 
867  * @param trail_id Identifier of trail to reach successor. 
868  * @param target_friend Message send to this friend. 
869  */
870 void
871 GDS_NEIGHBOURS_send_verify_successor_message (struct GNUNET_PeerIdentity source_peer,
872                                               struct GNUNET_PeerIdentity successor,
873                                               const struct GNUNET_HashCode trail_id,
874                                               struct FriendInfo *target_friend)
875 {
876   struct PeerVerifySuccessorMessage *vsm;
877   struct P2PPendingMessage *pending;
878   size_t msize;
879   
880   msize = sizeof (struct PeerVerifySuccessorMessage);
881   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
882   {
883     GNUNET_break (0);
884     return;
885   }
886  
887   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
888   {  
889     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
890                                 1, GNUNET_NO);
891   }
892   
893   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
894   pending->importance = 0;    /* FIXME */
895   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
896   vsm = (struct PeerVerifySuccessorMessage *) &pending[1];
897   pending->msg = &vsm->header;
898   vsm->header.size = htons (msize);
899   vsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR);
900   vsm->source_peer = source_peer;
901   vsm->successor = successor;
902   vsm->trail_id = trail_id;
903   
904   /* Send the message to chosen friend. */
905   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
906   target_friend->pending_count++;
907   process_friend_queue (target_friend);
908 }
909
910
911 /**
912  * 
913  * @param source_peer
914  * @param destination_peer
915  * @param trail_id
916  * @param trail_direction
917  * @param target_friend
918  */
919 void
920 GDS_NEIGHBOURS_send_trail_teardown (struct GNUNET_PeerIdentity source_peer,
921                                     struct GNUNET_PeerIdentity destination_peer,
922                                     struct GNUNET_HashCode trail_id,
923                                     enum GDS_ROUTING_trail_direction trail_direction,
924                                     struct FriendInfo *target_friend)
925 {
926   
927 }
928
929
930 /**
931  * 
932  * @param destination_peer
933  * @param source_successor
934  * @param succ_predecessor
935  * @param trail_id
936  * @param trail
937  * @param trail_length
938  * @param target_friend
939  */
940 void
941 GDS_NEIGHBOURS_send_verify_successor_result (struct GNUNET_PeerIdentity destination_peer,
942                                              struct GNUNET_PeerIdentity source_successor,
943                                              struct GNUNET_PeerIdentity succ_predecessor,
944                                              struct GNUNET_HashCode trail_id,
945                                              const struct GNUNET_PeerIdentity *trail,
946                                              unsigned int trail_length,
947                                              enum GDS_ROUTING_trail_direction trail_direction,
948                                              struct FriendInfo *target_friend)
949 {
950   struct PeerVerifySuccessorResultMessage *vsmr;
951   struct P2PPendingMessage *pending;
952   struct GNUNET_PeerIdentity *peer_list;
953   size_t msize;
954   
955   msize = sizeof (struct PeerVerifySuccessorResultMessage) + 
956           (trail_length * sizeof(struct GNUNET_PeerIdentity));
957   
958   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
959   {
960     GNUNET_break (0);
961     return;
962   }
963   
964   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
965   {  
966     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
967                                 1, GNUNET_NO);
968   }
969
970   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
971   pending->importance = 0;    /* FIXME */
972   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
973   vsmr = (struct PeerVerifySuccessorResultMessage *) &pending[1];
974   pending->msg = &vsmr->header;
975   vsmr->header.size = htons (msize);
976   vsmr->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR_RESULT);
977   vsmr->destination_peer = destination_peer;
978   vsmr->my_predecessor = succ_predecessor;
979   vsmr->source_successor = source_successor;
980   vsmr->trail_direction = htonl (trail_direction);
981   
982   if (trail_length > 0)
983   {
984     peer_list = (struct GNUNET_PeerIdentity *) &vsmr[1];
985     memcpy (peer_list, trail, trail_length * sizeof (struct GNUNET_PeerIdentity));
986   }
987   
988    /* Send the message to chosen friend. */
989   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
990   target_friend->pending_count++;
991   process_friend_queue (target_friend);
992 }
993
994
995 /**
996  * 
997  * @param source_peer
998  * @param new_successor
999  * @param new_successor_trail
1000  * @param new_successor_trail_length
1001  * @param new_succesor_trail_id
1002  */
1003 void 
1004 GDS_NEIGHBOURS_send_notify_new_successor (struct GNUNET_PeerIdentity source_peer,
1005                                           struct GNUNET_PeerIdentity new_successor,
1006                                           struct GNUNET_PeerIdentity *new_successor_trail,
1007                                           unsigned int new_successor_trail_length,
1008                                           struct GNUNET_HashCode new_succesor_trail_id,
1009                                           struct FriendInfo *target_friend)
1010 {
1011   struct PeerNotifyNewSuccessorMessage *nsm;
1012   struct P2PPendingMessage *pending;
1013   struct GNUNET_PeerIdentity *peer_list;
1014   size_t msize;
1015   
1016   msize = sizeof (struct PeerNotifyNewSuccessorMessage) + 
1017           (new_successor_trail_length * sizeof(struct GNUNET_PeerIdentity));
1018   
1019   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1020   {
1021     GNUNET_break (0);
1022     return;
1023   }
1024   
1025   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1026   {  
1027     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1028                                 1, GNUNET_NO);
1029   }
1030   
1031   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
1032   pending->importance = 0;    /* FIXME */
1033   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1034   nsm = (struct PeerNotifyNewSuccessorMessage *) &pending[1];
1035   pending->msg = &nsm->header;
1036   nsm->header.size = htons (msize);
1037   nsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_NEW_SUCCESSOR);
1038   nsm->source_peer = source_peer;
1039   nsm->destination_peer = new_successor;
1040   nsm->trail_length = htonl (new_successor_trail_length);
1041   nsm->trail_id = new_succesor_trail_id;
1042   if (new_successor_trail_length > 0)
1043   {
1044     peer_list = (struct GNUNET_PeerIdentity *) &nsm[1];
1045     memcpy (peer_list, new_successor_trail, 
1046             new_successor_trail_length * sizeof (struct GNUNET_PeerIdentity));
1047   }
1048   
1049    /* Send the message to chosen friend. */
1050   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1051   target_friend->pending_count++;
1052   process_friend_queue (target_friend);
1053 }
1054
1055
1056 /**
1057  * Send a trail compression message to target_friend.
1058  * @param source_peer Source of the trail. 
1059  * @param destination_finger Destination of trail. 
1060  * @param trail_id Unique identifier of trail.
1061  * @param first_friend First hop in compressed trail to reach from source to finger
1062  * @param target_friend Next friend to get this message. 
1063  */
1064 void
1065 GDS_NEIGHBOURS_send_trail_compression (struct GNUNET_PeerIdentity source_peer,
1066                                        struct GNUNET_PeerIdentity destination_peer,
1067                                        struct GNUNET_HashCode trail_id,
1068                                        struct GNUNET_PeerIdentity first_friend,
1069                                        struct FriendInfo *target_friend)
1070 {
1071   struct P2PPendingMessage *pending;
1072   struct PeerTrailCompressionMessage *tcm;
1073   size_t msize;
1074   
1075   msize = sizeof (struct PeerTrailCompressionMessage);
1076   
1077   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1078   {
1079     GNUNET_break (0);
1080     return;
1081   }
1082   
1083   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1084   {  
1085     GNUNET_STATISTICS_update (GDS_stats, 
1086                               gettext_noop ("# P2P messages dropped due to full queue"),
1087                                                       1, GNUNET_NO);
1088   }
1089   
1090   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
1091   pending->importance = 0;    /* FIXME */
1092   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1093   tcm = (struct PeerTrailCompressionMessage *) &pending[1];
1094   pending->msg = &tcm->header;
1095   tcm->header.size = htons (msize);
1096   tcm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_COMPRESSION);
1097   tcm->source_peer = source_peer;
1098   tcm->new_first_friend = first_friend;
1099   tcm->trail_id = trail_id;
1100   tcm->destination_peer = destination_peer;
1101   
1102   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1103   target_friend->pending_count++;
1104   process_friend_queue (target_friend);
1105   
1106 }
1107
1108 /**  
1109  * Construct a Put message and send it to target_peer. 
1110  * @param key Key for the content  
1111  * @param block_type Type of the block
1112  * @param options Routing options
1113  * @param desired_replication_level Desired replication count
1114  * @param current_destination Next current destination which will get this message.
1115  * @param current_source Source for @a current_destination
1116  * @param target_peer Peer to which this message will be forwarded.
1117  * @param hop_count Number of hops traversed so far.
1118  * @param put_path_length Total number of peers in @a put_path
1119  * @param put_path Number of peers traversed so far 
1120  * @param expiration_time When does the content expire
1121  * @param data Content to store
1122  * @param data_size Size of content @a data in bytes
1123  */
1124 void
1125 GDS_NEIGHBOURS_send_put (const struct GNUNET_HashCode *key,
1126                          enum GNUNET_BLOCK_Type block_type,
1127                          enum GNUNET_DHT_RouteOption options,
1128                          uint32_t desired_replication_level,
1129                          struct GNUNET_PeerIdentity current_destination,
1130                          struct GNUNET_PeerIdentity current_source,
1131                          struct GNUNET_PeerIdentity *target_peer,
1132                          uint32_t hop_count,
1133                          uint32_t put_path_length,
1134                          struct GNUNET_PeerIdentity *put_path,
1135                          struct GNUNET_TIME_Absolute expiration_time,
1136                          const void *data, size_t data_size)
1137 {
1138   
1139 }
1140
1141 /** 
1142  * Construct a Get message and send it to target_peer. 
1143  * @param key Key for the content  
1144  * @param block_type Type of the block
1145  * @param options Routing options
1146  * @param desired_replication_level Desired replication count
1147  * @param current_destination Next current destination which will get this message.
1148  * @param current_source Source for @a current_destination
1149  * @param target_peer Peer to which this message will be forwarded.
1150  * @param hop_count Number of hops traversed so far.
1151  * @param data Content to store
1152  * @param data_size Size of content @a data in bytes
1153  * @param get_path_length Total number of peers in @a get_path
1154  * @param get_path Number of peers traversed so far
1155  */
1156 void
1157 GDS_NEIGHBOURS_send_get (const struct GNUNET_HashCode *key,
1158                          enum GNUNET_BLOCK_Type block_type,
1159                          enum GNUNET_DHT_RouteOption options,
1160                          uint32_t desired_replication_level,
1161                          struct GNUNET_PeerIdentity current_destination,
1162                          struct GNUNET_PeerIdentity current_source,
1163                          struct GNUNET_PeerIdentity *target_peer,
1164                          uint32_t hop_count,
1165                          uint32_t get_path_length,
1166                          struct GNUNET_PeerIdentity *get_path)
1167 {
1168   
1169 }
1170
1171
1172 /**
1173  * Send the get result to requesting client.
1174  * @param key Key of the requested data.
1175  * @param type Block type
1176  * @param target_peer Next peer to forward the message to. 
1177  * @param source_peer Peer which has the data for the key.
1178  * @param put_path_length Number of peers in @a put_path
1179  * @param put_path Path taken to put the data at its stored location.
1180  * @param get_path_length Number of peers in @a get_path
1181  * @param get_path Path taken to reach to the location of the key.
1182  * @param expiration When will this result expire?
1183  * @param data Payload to store
1184  * @param data_size Size of the @a data 
1185  */
1186 void 
1187 GDS_NEIGHBOURS_send_get_result (const struct GNUNET_HashCode *key,
1188                                 enum GNUNET_BLOCK_Type type, 
1189                                 struct GNUNET_PeerIdentity *target_peer,
1190                                 struct GNUNET_PeerIdentity *source_peer,
1191                                 unsigned int put_path_length,
1192                                 const struct GNUNET_PeerIdentity *put_path,
1193                                 unsigned int get_path_length,
1194                                 struct GNUNET_PeerIdentity *get_path,
1195                                 struct GNUNET_TIME_Absolute expiration,
1196                                 const void *data, size_t data_size)
1197 {
1198   
1199 }
1200
1201
1202 /**
1203  * Seach my location in trail. 
1204  * @param trail List of peers
1205  * @return my_index if found
1206  *         #GNUNET_SYSERR if no entry found. 
1207  */
1208 static int
1209 search_my_index (const struct GNUNET_PeerIdentity *trail,
1210                  int trail_length)
1211 {
1212   int i;
1213   
1214   for (i = 0; i < trail_length; i++)
1215   {
1216     if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &trail[i]))
1217       return i;
1218   }
1219   
1220   return GNUNET_SYSERR;
1221 }
1222
1223
1224 /**
1225  * Find the successor for destination_finger_value among my_identity, all my
1226  * friend and all my fingers. Don't consider friends/ fingers with first friend in
1227  * the trail which are congested or have crossed the threshold. 
1228  * @param destination_finger_value Peer closest to this value will be the next successor.
1229  * @param next_destination [out] Updated to friend identity in case a friend is 
1230  *                               successor, updated to first friend to reach to finger
1231  *                               in case finger is the destination. 
1232  * @param new_intermediate_trail_id [out] In case we finger is the @a next_destination,
1233  *                                then we updated the field with trail id to reach 
1234  *                                to that finger. 
1235  * @param finger_map_index Index in finger peermap for which we are looking for a finger. 
1236  * @return 
1237  */
1238 static struct GNUNET_PeerIdentity *
1239 find_successor (uint64_t destination_finger_value,
1240                 struct GNUNET_PeerIdentity *next_destination,
1241                 struct GNUNET_HashCode *new_intermediate_trail_id,
1242                 unsigned int finger_map_index)
1243 {
1244   /* FIXME; IMPLEMENT*/
1245   return NULL;
1246 }
1247
1248
1249 /**
1250  * Select closest finger to value.
1251  * @param peer1 First peer
1252  * @param peer2 Second peer
1253  * @param value Value to be compare
1254  * @return Closest peer
1255  */
1256 static struct GNUNET_PeerIdentity *
1257 select_closest_finger (struct GNUNET_PeerIdentity *peer1,
1258                        struct GNUNET_PeerIdentity *peer2,
1259                        uint64_t value)
1260 {
1261   uint64_t peer1_value;
1262   uint64_t peer2_value;
1263   
1264   memcpy (&peer1_value, peer1, sizeof (uint64_t));
1265   memcpy (&peer2_value, peer2, sizeof (uint64_t));
1266   
1267   if ((peer1_value <= value) && (value <= peer2_value))
1268     return peer2;
1269   else if ((peer2_value <= value) && (value <= peer1_value))
1270     return peer1;
1271   else if ((peer1_value <= peer2_value) && (peer2_value <= value))
1272     return peer1;
1273   else if ((peer2_value <= peer1_value) && (peer1_value <= value))
1274     return peer2;
1275   else if ((value <= peer1_value) && (peer1_value <= peer2_value))
1276     return peer1;
1277   else /*if ((value <= peer2_value) && (peer2_value <= peer1_value))*/
1278     return peer2;
1279 }
1280
1281
1282 /**
1283  * Select closest predecessor to value.
1284  * @param peer1 First peer
1285  * @param peer2 Second peer
1286  * @param value Value to be compare
1287  * @return Closest peer
1288  */
1289 static struct GNUNET_PeerIdentity *
1290 select_closest_predecessor (struct GNUNET_PeerIdentity *peer1,
1291                             struct GNUNET_PeerIdentity *peer2,
1292                             uint64_t value)
1293 {
1294   uint64_t peer1_value;
1295   uint64_t peer2_value;
1296   
1297   memcpy (&peer1_value, peer1, sizeof (uint64_t));
1298   memcpy (&peer2_value, peer2, sizeof (uint64_t));
1299   
1300   if ((peer1_value <= value) && (value <= peer2_value))
1301     return peer1;
1302   else if ((peer2_value <= value) && (value <= peer1_value))
1303     return peer2;
1304   else if ((peer1_value <= peer2_value) && (peer2_value <= value))
1305     return peer2;
1306   else if ((peer2_value <= peer1_value) && (peer1_value <= value))
1307     return peer1;
1308   else if ((value <= peer1_value) && (peer1_value <= peer2_value))
1309     return peer2;
1310   else /*if ((value <= peer2_value) && (peer2_value <= peer1_value))*/
1311     return peer1;
1312 }
1313
1314
1315 /**
1316  * Select the closest peer among two peers (which should not be same)
1317  * with respect to value and finger_map_index
1318  * @param peer1 First peer
1319  * @param peer2 Second peer
1320  * @param value Value relative to which we find the closest
1321  * @param finger_map_index Index in finger map. If equal to PREDECESSOR_FINGER_ID,
1322  *                         then we use different logic than other  
1323  *                         finger_map_index
1324  * @return Closest peer among two peers. 
1325  */
1326 static struct GNUNET_PeerIdentity *
1327 select_closest_peer (struct GNUNET_PeerIdentity *peer1,
1328                      struct GNUNET_PeerIdentity *peer2,
1329                      uint64_t value,
1330                      unsigned int finger_map_index)
1331 {
1332   struct GNUNET_PeerIdentity *closest_peer;
1333   
1334   if (PREDECESSOR_FINGER_ID == finger_map_index)
1335     closest_peer = select_closest_predecessor (peer1, peer2, value);
1336   else
1337     closest_peer = select_closest_finger (peer1, peer2, value);
1338   
1339   return closest_peer;
1340 }
1341
1342
1343
1344 /** 
1345  * Randomly choose one of your friends (which is not congested and have not crossed
1346  * trail threshold) from the friends_peer map
1347  * @return Friend Randomly chosen friend. 
1348  *         NULL in case friend peermap is empty, or all the friends are either
1349  *              congested or have crossed trail threshold. 
1350  */
1351 static struct FriendInfo *
1352 select_random_friend ()
1353 {  
1354   unsigned int current_size;
1355   uint32_t index; 
1356   unsigned int j = 0;
1357   struct GNUNET_CONTAINER_MultiPeerMapIterator *iter;
1358   struct GNUNET_PeerIdentity key_ret;
1359   struct FriendInfo *friend;
1360   
1361   current_size = GNUNET_CONTAINER_multipeermap_size (friend_peermap);
1362   if (0 == current_size)
1363     return NULL;
1364   
1365   index = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, current_size);
1366   iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap);
1367  
1368   for (j = 0; j < index ; j++)
1369     GNUNET_assert (GNUNET_YES == 
1370                    GNUNET_CONTAINER_multipeermap_iterator_next (iter, NULL, NULL));
1371   do
1372   {
1373     if (j == current_size)
1374     {
1375       j = 0;
1376       GNUNET_CONTAINER_multipeermap_iterator_destroy (iter);
1377       iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap);
1378       
1379     }
1380     GNUNET_assert (GNUNET_YES == 
1381                 GNUNET_CONTAINER_multipeermap_iterator_next (iter,
1382                                                              &key_ret,
1383                                                              (const void **)&friend));
1384   
1385  
1386     if ((TRAILS_THROUGH_FRIEND_THRESHOLD > friend->trails_count) &&
1387         (0 == GNUNET_TIME_absolute_get_remaining (friend->congestion_duration).rel_value_us))
1388     {
1389       break;
1390     }
1391     friend = NULL;
1392     j++;
1393   } while (j != index);
1394   
1395   GNUNET_CONTAINER_multipeermap_iterator_destroy (iter);
1396   return friend;
1397 }
1398
1399
1400 /**
1401  * Compute finger_identity to which we want to setup the trail
1402  * @return finger_identity 
1403  */
1404 static uint64_t 
1405 compute_finger_identity()
1406 {
1407   uint64_t my_id64;
1408
1409   memcpy (&my_id64, &my_identity, sizeof (uint64_t));
1410   my_id64 = GNUNET_ntohll (my_id64);
1411   return (my_id64 + (unsigned long) pow (2, current_search_finger_index));
1412 }
1413
1414
1415 /**
1416  * Compute immediate predecessor identity in the network.
1417  * @return peer identity of immediate predecessor.
1418  */
1419 static uint64_t 
1420 compute_predecessor_identity()
1421 {
1422   uint64_t my_id64;
1423
1424   memcpy (&my_id64, &my_identity, sizeof (uint64_t));
1425   my_id64 = GNUNET_ntohll (my_id64);
1426   return (my_id64 -1);
1427 }
1428
1429
1430 /*
1431  * Choose a random friend and start looking for the trail to reach to 
1432  * finger identity through this random friend. 
1433  *
1434  * @param cls closure for this task
1435  * @param tc the context under which the task is running
1436  */
1437 static void
1438 send_find_finger_trail_message (void *cls,
1439                                 const struct GNUNET_SCHEDULER_TaskContext *tc)
1440 {
1441   struct FriendInfo *target_friend;
1442   struct GNUNET_TIME_Relative next_send_time;
1443   struct GNUNET_HashCode trail_id;
1444   struct GNUNET_HashCode intermediate_trail_id;
1445   unsigned int finger_map_index;
1446   uint64_t finger_identity;
1447   
1448   next_send_time.rel_value_us =
1449       DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us +
1450       GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
1451                                 DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us);
1452   find_finger_trail_task =
1453       GNUNET_SCHEDULER_add_delayed (next_send_time, &send_find_finger_trail_message,
1454                                     NULL);
1455   
1456   target_friend = select_random_friend (); 
1457   if (NULL == target_friend) 
1458   {
1459     return;
1460   }
1461   
1462   if (PREDECESSOR_FINGER_ID == current_search_finger_index)
1463   {
1464     finger_identity = compute_predecessor_identity();  
1465   }
1466   else
1467   {
1468     finger_identity = compute_finger_identity();
1469   }
1470     
1471   finger_map_index = current_search_finger_index;
1472   
1473   /* FIXME: Find the correct function to generate a random trail id which is of
1474    * type struct GNUNET_HashCode. */
1475   //trail_id = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
1476   
1477   GDS_NEIGHBOURS_send_trail_setup (my_identity, finger_identity, 
1478                                    target_friend->id, target_friend, 0, NULL,
1479                                    finger_map_index, trail_id, intermediate_trail_id);
1480 }
1481
1482
1483 /**
1484  * In case there are already maximum number of possible trail to reach to a finger,
1485  * then check if the new trail's length is lesser than any of the existing trails.
1486  * If yes then replace that old trail by new trail.
1487  * Note: Here we are taking length as a parameter to choose the best possible trail,
1488  * but there could be other parameters also like - 1. duration of existence of a
1489  * trail - older the better. 2. if the new trail is completely disjoint than the 
1490  * other trails, then may be choosing it is better. 
1491  * @param existing_finger
1492  * @param new_finger_trail
1493  * @param new_finger_trail_length
1494  * @param new_finger_trail_id
1495  */
1496 static void
1497 select_and_replace_trail (struct FingerInfo *existing_finger, 
1498                           struct GNUNET_PeerIdentity *new_trail,
1499                           unsigned int new_trail_length, 
1500                           struct GNUNET_HashCode new_trail_id)
1501 {
1502   struct TrailList *trail_list_iterator;
1503   unsigned int largest_trail_length;
1504   unsigned int largest_trail_index;
1505   struct Trail *trail_element;
1506   unsigned int i;
1507   
1508   largest_trail_length = new_trail_length;
1509   largest_trail_index = MAXIMUM_TRAILS_PER_FINGER + 1;
1510   
1511   GNUNET_assert (MAXIMUM_TRAILS_PER_FINGER == existing_finger->trails_count);
1512   
1513   for (i = 0; i < existing_finger->trails_count; i++)
1514   {
1515     trail_list_iterator = &existing_finger->trail_list[i];
1516     if (trail_list_iterator->trail_length > largest_trail_length)
1517     {
1518       largest_trail_length = trail_list_iterator->trail_length;
1519       largest_trail_index = i;
1520     }
1521   }
1522   
1523   if (largest_trail_index == (MAXIMUM_TRAILS_PER_FINGER + 1))
1524     return;
1525   
1526   /* Send trail teardown message across the replaced trail. */
1527   struct TrailList *replace_trail = &existing_finger->trail_list[largest_trail_index];
1528   struct FriendInfo *target_friend = 
1529   GNUNET_CONTAINER_multipeermap_get (friend_peermap,
1530                                      &replace_trail->trail_head->peer);
1531   
1532   GDS_NEIGHBOURS_send_trail_teardown (my_identity, 
1533                                       existing_finger->finger_identity, 
1534                                       replace_trail->trail_id, 
1535                                       GDS_ROUTING_SRC_TO_DEST, target_friend);
1536   /* Free the trail .*/
1537   while (NULL != (trail_element = replace_trail->trail_head))
1538   {
1539     GNUNET_CONTAINER_DLL_remove (replace_trail->trail_head,
1540                                  replace_trail->trail_tail, trail_element);
1541     GNUNET_free (trail_element);
1542   }
1543   
1544   /* Add new trial at that location. */
1545   i = 0;
1546   while ( i < new_trail_length)
1547   {
1548     struct Trail *element = GNUNET_new (struct Trail);
1549     element->next = NULL;
1550     element->prev = NULL;
1551     element->peer = new_trail[0];
1552     
1553     GNUNET_CONTAINER_DLL_insert_tail (replace_trail->trail_head, 
1554                                       replace_trail->trail_tail,
1555                                       element);
1556   }
1557 }
1558
1559
1560 /**
1561  * Check if the new trail to reach to finger is unique or do we already have
1562  * such a trail present for finger. 
1563  * @param existing_finger Finger identity 
1564  * @param new_trail New trail to reach @a existing_finger
1565  * @param trail_length Total number of peers in new_trail.
1566  * @return #GNUNET_YES if the new trail is unique
1567  *         #GNUNET_NO if same trail is already present. 
1568  */
1569 static int
1570 is_new_trail_unique (struct FingerInfo *existing_finger,
1571                      struct GNUNET_PeerIdentity *new_trail,
1572                      unsigned int trail_length)
1573 {
1574   struct TrailList *trail_list_iterator;
1575   struct Trail *trail_element;
1576   int i;
1577   int j;
1578   int trail_unique = GNUNET_NO;
1579   
1580   for (i = 0; i < existing_finger->trails_count; i++)
1581   {
1582     trail_list_iterator = &existing_finger->trail_list[i];
1583     trail_element = trail_list_iterator->trail_head;
1584     for (j = 0; j < trail_list_iterator->trail_length; j++)
1585     {
1586       if (0 != GNUNET_CRYPTO_cmp_peer_identity (&new_trail[j],
1587                                                  &trail_element->peer))
1588       {
1589         trail_unique = GNUNET_YES;
1590         break;
1591       }
1592     }
1593   }
1594   return trail_unique;
1595 }
1596
1597
1598 /**
1599  * Add a new trail to existing finger. 
1600  * @param existing_finger
1601  * @param new_finger_trail
1602  * @param new_finger_trail_length
1603  * @param new_finger_trail_id
1604  */
1605 static void
1606 add_new_trail (struct FingerInfo *existing_finger, 
1607                struct GNUNET_PeerIdentity *new_trail,
1608                unsigned int new_trail_length, 
1609                struct GNUNET_HashCode new_trail_id)
1610 {
1611   struct TrailList *trail_list_iterator;
1612   struct FriendInfo *first_friend;
1613   int i = 0;
1614   int j;
1615   
1616   if (GNUNET_NO == is_new_trail_unique (existing_finger,
1617                                          new_trail,
1618                                          new_trail_length))
1619     return;
1620   
1621   do
1622   {
1623     trail_list_iterator = &existing_finger->trail_list[i];
1624     i++;
1625   } while (trail_list_iterator->trail_head != NULL);
1626   
1627   if (new_trail_length > 0)
1628     first_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, 
1629                                                       &new_trail[0]);
1630   else
1631     first_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap,
1632                                                       &(existing_finger->finger_identity));
1633   first_friend->trails_count++;
1634   trail_list_iterator->first_friend_trail_count = first_friend->trails_count;
1635   trail_list_iterator->trail_length = new_trail_length;
1636   
1637   for (j = 0; j < new_trail_length; j++)
1638   {
1639     struct Trail *element;
1640     element = GNUNET_new (struct Trail);
1641     
1642     element->next = NULL;
1643     element->prev = NULL;
1644     element->peer = new_trail[j];
1645     GNUNET_CONTAINER_DLL_insert_tail (trail_list_iterator->trail_head, 
1646                                       trail_list_iterator->trail_tail,
1647                                       element);
1648   }
1649   existing_finger->trails_count++;
1650 }
1651
1652
1653 /**
1654  * Send trail teardown message on all trails associated with finger. 
1655  * @param finger_to_be_removed
1656  */
1657 static void
1658 send_trail_teardown (struct FingerInfo *finger)
1659 {
1660   struct TrailList *trail_list_iterator;
1661   struct GNUNET_HashCode trail_id;
1662   struct FriendInfo *target_friend;
1663   int i;
1664   
1665   if (0 == GNUNET_CRYPTO_cmp_peer_identity (&finger->finger_identity, &my_identity)
1666      || (NULL != GNUNET_CONTAINER_multipeermap_get (friend_peermap, 
1667                                                     &finger->finger_identity)))
1668     return;
1669   
1670   for (i = 0; i < finger->trails_count; i++)
1671   {
1672     trail_list_iterator = &finger->trail_list[i];
1673     if (trail_list_iterator->trail_length > 0)
1674     {
1675       trail_id = trail_list_iterator->trail_id;
1676       target_friend = 
1677               GNUNET_CONTAINER_multipeermap_get (friend_peermap,
1678                                                  &trail_list_iterator->trail_head->peer);
1679     GDS_NEIGHBOURS_send_trail_teardown (my_identity, finger->finger_identity,
1680                                         trail_id, GDS_ROUTING_SRC_TO_DEST,
1681                                         target_friend);
1682     }
1683   }
1684 }
1685
1686
1687 /**
1688  * Decrement the trail count of the first friend to reach the finger
1689  * In case finger is the friend, then decrement its trail count.
1690  * @param finger
1691  */
1692 static void
1693 decrement_friend_trail_count (struct FingerInfo *finger)
1694 {
1695   struct TrailList *trail_list_iterator;
1696   struct FriendInfo *target_friend;
1697   int i = 0;
1698   
1699   if (0 == GNUNET_CRYPTO_cmp_peer_identity (&finger->finger_identity,
1700                                             &my_identity))
1701     return;
1702   
1703   for (i = 0; i < finger->trails_count; i++)
1704   {
1705     trail_list_iterator = &finger->trail_list[i];
1706     if (trail_list_iterator->trail_length > 0)
1707       target_friend = 
1708               GNUNET_CONTAINER_multipeermap_get (friend_peermap, 
1709                                                  &trail_list_iterator->trail_head->peer);
1710     else
1711      target_friend = 
1712               GNUNET_CONTAINER_multipeermap_get (friend_peermap, 
1713                                                  &finger->finger_identity);
1714     
1715     target_friend->trails_count--;
1716     trail_list_iterator->first_friend_trail_count--;
1717   }
1718   return;
1719 }
1720
1721
1722 /**
1723  * Free finger and its trail.  
1724  * @param finger Finger to be freed.
1725  */
1726 static void
1727 free_finger (struct FingerInfo *finger)
1728 {
1729   struct TrailList *trail_list_iterator;
1730   struct Trail *trail_element;
1731   unsigned int i;
1732   
1733   for (i = 0; i < finger->trails_count; i++)
1734   {
1735     trail_list_iterator = &finger->trail_list[i];
1736     while (NULL != (trail_element = trail_list_iterator->trail_head))
1737     {
1738       GNUNET_CONTAINER_DLL_remove (trail_list_iterator->trail_head,
1739                                    trail_list_iterator->trail_tail, trail_element);
1740       GNUNET_free (trail_element);
1741     }
1742   }
1743   GNUNET_free (finger);
1744 }
1745
1746
1747 /**
1748  * Check if new finger is closer than existing_finger. If both new finger and 
1749  * existing finger are same then we may add a new trail (if there is space)
1750  * or choose the best trail among existing trails and new trails.
1751  * @param existing_finger Finger present in finger_peermap at @a finger_map_index
1752  * @param new_finger_identity Peer identity of new finger.
1753  * @param new_finger_trail Trail to reach from source to new_finger. 
1754  * @param new_finger_trail_length Total number of peers in @a new_finger_trail.
1755  * @param trail_id Unique identifier of trail. 
1756  * @param finger_map_index Index in finger map. 
1757  * @return #GNUNET_YES if the new finger is closest.
1758  *         #GNUNET_NO either new_finger and existing_finger are same, or 
1759  *                    existing_finger is closest.
1760  */
1761 static int
1762 is_new_finger_closest (struct FingerInfo *existing_finger, 
1763                        struct GNUNET_PeerIdentity new_finger_identity,
1764                        struct GNUNET_PeerIdentity *new_finger_trail,
1765                        unsigned int new_finger_trail_length,
1766                        struct GNUNET_HashCode new_finger_trail_id,
1767                        unsigned int finger_map_index)
1768 {
1769   struct GNUNET_PeerIdentity *closest_peer;
1770   uint64_t my_id64;
1771   
1772   if (NULL == existing_finger)
1773     return GNUNET_YES;
1774   
1775   if (0 != GNUNET_CRYPTO_cmp_peer_identity (&(existing_finger->finger_identity),
1776                                             &new_finger_identity))
1777   {
1778     memcpy (&my_id64, &my_identity, sizeof (uint64_t));
1779     closest_peer = select_closest_peer (&existing_finger->finger_identity,
1780                                         &new_finger_identity,
1781                                         my_id64, finger_map_index);
1782   
1783     if (0 == GNUNET_CRYPTO_cmp_peer_identity (&new_finger_identity, closest_peer))
1784     {
1785       if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, 
1786                                                 &new_finger_identity)) /* FIXME: not sure what to do here? */
1787         return GNUNET_NO;
1788     
1789       send_trail_teardown (existing_finger);
1790       decrement_friend_trail_count (existing_finger);
1791       free_finger (existing_finger);
1792       return GNUNET_YES;
1793     }
1794   }
1795   else
1796   {
1797     if (0 != GNUNET_CRYPTO_cmp_peer_identity (&(existing_finger->finger_identity), 
1798                                               &my_identity))
1799     {
1800       if (NULL == 
1801           GNUNET_CONTAINER_multipeermap_get (friend_peermap,
1802                                              &(existing_finger->finger_identity)))
1803       {
1804         if (existing_finger->trails_count < MAXIMUM_TRAILS_PER_FINGER)
1805           add_new_trail (existing_finger, new_finger_trail,
1806                          new_finger_trail_length, new_finger_trail_id);
1807         else
1808           select_and_replace_trail (existing_finger, new_finger_trail,
1809                                     new_finger_trail_length, new_finger_trail_id); 
1810       }
1811     }
1812   } 
1813   return GNUNET_NO;
1814 }
1815
1816
1817 /**
1818  * Add a new entry in finger hashmap at finger_map_index
1819  * @param finger_identity Peer Identity of new finger
1820  * @param finger_trail Trail to reach from me to finger (excluding both end points).
1821  * @param finger_trail_length Total number of peers in @a finger_trail.
1822  * @param trail_id Unique identifier of the trail. 
1823  * @param finger_map_index Index in finger hashmap. 
1824  * @return #GNUNET_OK if new entry is added
1825  *         #GNUNET_NO -- FIXME: need to check what value does hahsmap put
1826  *                       returns on failure. 
1827  */
1828 static int
1829 add_new_entry (struct GNUNET_PeerIdentity finger_identity,
1830                struct GNUNET_PeerIdentity *finger_trail,
1831                unsigned int finger_trail_length,
1832                struct GNUNET_HashCode trail_id,
1833                unsigned int finger_map_index)
1834 {
1835   struct FingerInfo *new_entry;
1836   struct FriendInfo *first_trail_hop;
1837   struct TrailList *first_trail;
1838   int i = 0;
1839   
1840   new_entry = GNUNET_new (struct FingerInfo);
1841   new_entry->finger_identity = finger_identity;
1842   new_entry->finger_map_index = finger_map_index;
1843   new_entry->trails_count = 1;
1844   
1845   if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &finger_identity))
1846   {
1847     if (finger_trail_length > 0)
1848     {
1849       first_trail_hop = GNUNET_CONTAINER_multipeermap_get (friend_peermap,
1850                                                            &finger_trail[0]);
1851     }
1852     else
1853     {
1854       first_trail_hop = GNUNET_CONTAINER_multipeermap_get (friend_peermap,
1855                                                            &finger_identity);
1856     }
1857     
1858     first_trail_hop->trails_count++;
1859     first_trail = &new_entry->trail_list[0];
1860     first_trail->first_friend_trail_count = first_trail_hop->trails_count;
1861     
1862     while (i < finger_trail_length)
1863     {
1864       struct Trail *element = GNUNET_new (struct Trail);
1865       
1866       element->next = NULL;
1867       element->prev = NULL;
1868       element->peer = finger_trail[i];
1869       GNUNET_CONTAINER_DLL_insert_tail (first_trail->trail_head, 
1870                                         first_trail->trail_tail,
1871                                         element);
1872       i++;
1873     }
1874   }
1875  
1876   return GNUNET_CONTAINER_multihashmap32_put (finger_hashmap, 
1877                                               new_entry->finger_map_index,
1878                                               new_entry,
1879                                               GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);   
1880 }
1881
1882
1883 /**
1884  * Scan the trail to check if there is any other friend in the trail other than
1885  * first hop. If yes the shortcut the trail, send trail compression message to
1886  * peers which are no longer part of trail and send back the updated trail
1887  * and trail_length to calling function. 
1888  * @param finger_identity Finger whose trail we will scan. 
1889  * @param finger_trail [in, out] Trail to reach from source to finger,              
1890  * @param finger_trail_length  Total number of peers in original finger_trail.
1891  * @param finger_trail_id Unique identifier of the finger trail.
1892  * @return updated trail length in case we shortcut the trail, else original
1893  *         trail length.  
1894  */
1895 static int
1896 scan_and_compress_trail (struct GNUNET_PeerIdentity finger_identity,
1897                          struct GNUNET_PeerIdentity *trail,
1898                          unsigned int trail_length,
1899                          struct GNUNET_HashCode trail_id)
1900 {
1901   struct FriendInfo *target_friend;
1902   int i;
1903   
1904   if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &finger_identity))
1905   {
1906     trail = NULL;
1907     return 0;
1908   }
1909   
1910   if (GNUNET_CONTAINER_multipeermap_get (friend_peermap, &finger_identity))
1911   {
1912     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, 
1913                                                        &trail[0]);
1914     GDS_NEIGHBOURS_send_trail_compression (my_identity, finger_identity, 
1915                                            trail_id, finger_identity, 
1916                                            target_friend);
1917     trail = NULL;
1918     return 0;
1919   }
1920   
1921   for ( i = trail_length - 1; i > 0; i--)
1922   {
1923     if (NULL != GNUNET_CONTAINER_multipeermap_get (friend_peermap, &trail[i]))
1924     {
1925       struct FriendInfo *target_friend;
1926       int j = 0;
1927
1928       target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, 
1929                                                          &trail[0]);
1930       GDS_NEIGHBOURS_send_trail_compression (my_identity, finger_identity, 
1931                                              trail_id, trail[i], 
1932                                              target_friend);
1933      
1934       /* Copy the trail from index i to index trail_length -1 and change
1935        trail length and return */
1936       while (i < trail_length)
1937       {
1938         memcpy (&trail[j], &trail[i], sizeof(struct GNUNET_PeerIdentity));
1939         j++;
1940         i++;
1941       }
1942       trail_length = j+1;
1943       break;
1944     }
1945   }
1946   return trail_length;
1947 }
1948
1949
1950 /**
1951  * Send verify successor message to your successor on all trails to reach successor.
1952  * @param successor My current successor 
1953  */
1954 static void
1955 send_verify_successor_message (struct FingerInfo *successor)
1956 {
1957   struct TrailList *trail_list_iterator;
1958   struct GNUNET_HashCode trail_id;
1959   struct GNUNET_PeerIdentity next_hop;
1960   struct FriendInfo *target_friend;
1961   int i;
1962   
1963   for (i = 0; i < successor->trails_count; i++)
1964   {
1965     trail_list_iterator = &successor->trail_list[i];
1966     if (trail_list_iterator->trail_length > 0)
1967       next_hop = trail_list_iterator->trail_head->peer;
1968     else
1969       next_hop = successor->finger_identity;
1970     
1971     trail_id = trail_list_iterator->trail_id;
1972     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
1973     GDS_NEIGHBOURS_send_verify_successor_message (my_identity,
1974                                                   successor->finger_identity,
1975                                                   trail_id, target_friend);
1976   }
1977 }
1978
1979
1980 /**
1981  * Check if there is already an entry in finger peermap for given finger map index.
1982  * If yes, then select the closest finger. If new and existing finger are same,
1983  * the check if you can store more trails. If yes then add trail, else keep the best
1984  * trails to reach to the finger. If the new finger is closest, add it.
1985  * Then, update current_search_finger_index.
1986  * @param new_finger_identity Peer Identity of new finger
1987  * @param new_finger_trail Trail to reach the new finger
1988  * @param new_finger_length Total number of peers in @a new_finger_trail.
1989  * @param finger_map_index Index in finger peermap.
1990  * @param new_finger_trail_id Unique identifier of @new_finger_trail.
1991  * @return #GNUNET_YES if the new entry is added
1992  *         #GNUNET_NO if new entry is not added, either it was discarded or
1993  *                    it was same as existing finger at finger map index.
1994  */
1995 static int
1996 finger_table_add (struct GNUNET_PeerIdentity new_finger_identity,
1997                   struct GNUNET_PeerIdentity *new_finger_trail,
1998                   unsigned int new_finger_trail_length,
1999                   unsigned int finger_map_index,
2000                   struct GNUNET_HashCode new_finger_trail_id)
2001 {
2002   struct FingerInfo *existing_finger;
2003   struct FingerInfo *successor;
2004   unsigned int new_entry_added = GNUNET_NO;
2005   
2006   int new_finger_updated_trail_length = 
2007        scan_and_compress_trail (new_finger_identity, new_finger_trail, 
2008                                 new_finger_trail_length, new_finger_trail_id);
2009  
2010   successor = GNUNET_CONTAINER_multihashmap32_get (finger_hashmap, 
2011                                                    finger_map_index);
2012   existing_finger = GNUNET_CONTAINER_multihashmap32_get (finger_hashmap,
2013                                                          finger_map_index);
2014   
2015   if  (GNUNET_YES == is_new_finger_closest (existing_finger,
2016                                             new_finger_identity,
2017                                             new_finger_trail, 
2018                                             new_finger_updated_trail_length,
2019                                             new_finger_trail_id, finger_map_index))
2020   {
2021     GNUNET_assert (GNUNET_YES == add_new_entry (new_finger_identity, 
2022                                                 new_finger_trail, 
2023                                                 new_finger_updated_trail_length, 
2024                                                 new_finger_trail_id, 
2025                                                 finger_map_index));
2026     new_entry_added = GNUNET_YES;
2027   }
2028   
2029   if (0 == finger_map_index)
2030   {   
2031     current_search_finger_index = PREDECESSOR_FINGER_ID;
2032  
2033     if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity,&new_finger_identity))
2034     {
2035       send_verify_successor_message (successor);
2036     }
2037   }
2038   else if (0 == GNUNET_CRYPTO_cmp_peer_identity (&new_finger_identity, 
2039                                                  &(successor->finger_identity)))
2040   {
2041     current_search_finger_index = 0;
2042   }
2043   else 
2044     current_search_finger_index = current_search_finger_index - 1;
2045   
2046   return new_entry_added;
2047 }
2048
2049
2050 /**
2051  * Core handler for P2P put messages. 
2052  * @param cls closure
2053  * @param peer sender of the request
2054  * @param message message
2055  * @return #GNUNET_OK to keep the connection open,
2056  *         #GNUNET_SYSERR to close it (signal serious error)
2057  */
2058 static int 
2059 handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer,
2060                     const struct GNUNET_MessageHeader *message)
2061 {
2062   return GNUNET_OK;
2063 }
2064
2065
2066 /**
2067  * Core handler for p2p get requests.
2068  *
2069  * @param cls closure
2070  * @param peer sender of the request
2071  * @param message message
2072  * @return #GNUNET_OK to keep the connection open,
2073  *         #GNUNET_SYSERR to close it (signal serious error)
2074  */
2075 static int
2076 handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer,
2077                     const struct GNUNET_MessageHeader *message)
2078 {
2079   return GNUNET_OK;
2080 }
2081
2082
2083 /**
2084  * Core handler for get result
2085  * @param cls closure
2086  * @param peer sender of the request
2087  * @param message message
2088  * @return #GNUNET_OK to keep the connection open,
2089  *         #GNUNET_SYSERR to close it (signal serious error)
2090  */
2091 static int
2092 handle_dht_p2p_get_result (void *cls, const struct GNUNET_PeerIdentity *peer,
2093                            const struct GNUNET_MessageHeader *message)
2094 {
2095   return GNUNET_OK;
2096 }
2097
2098
2099 /* Core handle for PeerTrailSetupMessage. 
2100  * @param cls closure
2101  * @param message message
2102  * @param peer peer identity this notification is about
2103  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
2104  */
2105 static int
2106 handle_dht_p2p_trail_setup (void *cls, const struct GNUNET_PeerIdentity *peer,
2107                             const struct GNUNET_MessageHeader *message)
2108 {
2109   struct PeerTrailSetupMessage *trail_setup; 
2110   struct GNUNET_PeerIdentity *trail_peer_list;
2111   struct GNUNET_PeerIdentity next_destination;
2112   struct GNUNET_PeerIdentity *current_destination;
2113   struct GNUNET_PeerIdentity *next_hop;
2114   struct GNUNET_PeerIdentity next_peer;
2115   struct FriendInfo *target_friend;
2116   struct GNUNET_PeerIdentity source;
2117   uint64_t ultimate_destination_finger_value;
2118   struct GNUNET_HashCode new_intermediate_trail_id;
2119   struct GNUNET_HashCode intermediate_trail_id;
2120   struct GNUNET_HashCode new_trail_id;
2121   unsigned int finger_map_index;
2122   uint32_t trail_length;
2123   size_t msize;
2124
2125   msize = ntohs (message->size);
2126   if (msize != sizeof (struct PeerTrailSetupMessage))
2127   {
2128     GNUNET_break_op (0);
2129     return GNUNET_YES;
2130   }
2131   
2132   trail_setup = (struct PeerTrailSetupMessage *) message;
2133   trail_length = ntohl (trail_setup->trail_length); 
2134   if ((msize != sizeof (struct PeerTrailSetupMessage) +
2135        trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
2136        (trail_length >
2137         GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2138   {
2139     GNUNET_break_op (0);
2140     return GNUNET_OK; 
2141   }
2142   
2143   trail_peer_list = (struct GNUNET_PeerIdentity *)&trail_setup[1];
2144   current_destination = &trail_setup->next_destination;
2145   intermediate_trail_id = trail_setup->intermediate_trail_id;
2146   new_trail_id = trail_setup->new_trail_id;
2147   ultimate_destination_finger_value = GNUNET_ntohll (trail_setup->ultimate_destination_finger);
2148   source = trail_setup->source_peer;
2149   finger_map_index = ntohl (trail_setup->finger_map_index);
2150   
2151   if (GNUNET_YES == GDS_ROUTING_threshold_reached())
2152   {
2153     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, peer);
2154     GDS_NEIGHBOURS_send_trail_rejection (source, ultimate_destination_finger_value,
2155                                          my_identity, finger_map_index,
2156                                          trail_peer_list, trail_length,
2157                                          new_trail_id, target_friend, 
2158                                          CONGESTION_TIMEOUT);
2159     return GNUNET_OK;
2160   }
2161   
2162   next_hop = find_successor (ultimate_destination_finger_value, &next_destination,
2163                              &new_intermediate_trail_id, finger_map_index);
2164   
2165   if (0 != (GNUNET_CRYPTO_cmp_peer_identity(&my_identity, current_destination)))
2166   {
2167     struct GNUNET_PeerIdentity *closest_peer;
2168     struct GNUNET_PeerIdentity *peer1 = 
2169     GDS_ROUTING_get_next_hop (intermediate_trail_id, GDS_ROUTING_SRC_TO_DEST);
2170     if (0 != GNUNET_CRYPTO_cmp_peer_identity (peer1, next_hop))
2171     {
2172        closest_peer = select_closest_peer (peer1, next_hop, 
2173                                            ultimate_destination_finger_value,
2174                                            finger_map_index);
2175     }
2176     if (0 == GNUNET_CRYPTO_cmp_peer_identity (peer1, closest_peer) ||
2177         (0 == GNUNET_CRYPTO_cmp_peer_identity (peer1, next_hop)))
2178     {
2179       next_hop = peer1;
2180       next_destination = *current_destination;
2181       new_intermediate_trail_id = intermediate_trail_id;
2182     }
2183   }
2184   
2185   GNUNET_assert (NULL != next_hop);
2186   if (0 == (GNUNET_CRYPTO_cmp_peer_identity (next_hop, &my_identity)))/* This means I am the final destination */
2187   {
2188     if (0 == trail_length)
2189       memcpy (&next_peer, &source, sizeof (struct GNUNET_PeerIdentity));
2190     else
2191       memcpy (&next_peer, &trail_peer_list[trail_length-1], sizeof (struct GNUNET_PeerIdentity));
2192     
2193     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_peer);
2194     GDS_NEIGHBOURS_send_trail_setup_result (source,
2195                                             my_identity,
2196                                             target_friend, trail_length,
2197                                             trail_peer_list,
2198                                             finger_map_index, new_trail_id);
2199   }
2200   else
2201   {
2202     struct GNUNET_PeerIdentity peer_list[trail_length + 1];
2203     
2204     memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
2205     peer_list[trail_length] = my_identity;
2206     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2207     GDS_NEIGHBOURS_send_trail_setup (source,
2208                                      ultimate_destination_finger_value,
2209                                      next_destination, 
2210                                      target_friend, trail_length + 1, peer_list, 
2211                                      finger_map_index, new_trail_id,
2212                                      new_intermediate_trail_id);
2213   }
2214   return GNUNET_OK;
2215 }
2216
2217
2218 /**
2219  * Core handle for p2p trail construction result messages.
2220  * @param closure
2221  * @param message message
2222  * @param peer peer identity this notification is about
2223  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
2224  */
2225 static int
2226 handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *peer,
2227                                   const struct GNUNET_MessageHeader *message)
2228 {
2229   struct PeerTrailSetupResultMessage *trail_result;
2230   struct GNUNET_PeerIdentity *trail_peer_list;
2231   struct GNUNET_PeerIdentity destination_peer;
2232   struct GNUNET_PeerIdentity finger_identity;    
2233   uint32_t trail_length;
2234   uint32_t finger_map_index;
2235   struct GNUNET_HashCode trail_id;
2236   size_t msize;
2237   
2238   msize = ntohs (message->size);
2239   if (msize != sizeof (struct PeerTrailSetupResultMessage))
2240   {
2241     GNUNET_break_op (0);
2242     return GNUNET_YES;
2243   }
2244   
2245   trail_result = (struct PeerTrailSetupResultMessage *) message; 
2246   trail_length = ntohl (trail_result->trail_length); 
2247   
2248   if ((msize !=
2249        sizeof (struct PeerTrailSetupResultMessage) +
2250        trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
2251        (trail_length >
2252         GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2253   {
2254     GNUNET_break_op (0);
2255     return GNUNET_YES;
2256   }
2257   
2258   finger_map_index = htonl (trail_result->finger_map_index);
2259   destination_peer = trail_result->destination_peer;
2260   finger_identity = trail_result->finger_identity;
2261   trail_id = trail_result->trail_id;
2262   trail_peer_list = (struct GNUNET_PeerIdentity *) &trail_result[1];
2263   
2264   if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&destination_peer,
2265                                              &my_identity)))
2266   {
2267     finger_table_add (finger_identity, trail_peer_list, 
2268                       trail_length, 
2269                       finger_map_index, trail_id);
2270     return GNUNET_YES;
2271   }
2272   
2273   struct GNUNET_PeerIdentity next_hop;
2274   struct FriendInfo *target_friend;
2275   int my_index;
2276
2277   my_index = search_my_index(trail_peer_list, trail_length);
2278   if (my_index == GNUNET_SYSERR) 
2279   {
2280     GNUNET_break_op(0);
2281     return GNUNET_SYSERR;
2282   }
2283   
2284   if (my_index == 0)
2285     next_hop = trail_result->destination_peer;
2286   else
2287     next_hop = trail_peer_list[my_index - 1];
2288   
2289   if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&(trail_result->destination_peer),
2290                                                &(trail_result->finger_identity))))
2291   {
2292     GDS_ROUTING_add (trail_id, &next_hop, peer);
2293   }
2294   
2295   target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
2296   GDS_NEIGHBOURS_send_trail_setup_result (destination_peer, finger_identity,
2297                                           target_friend, trail_length, trail_peer_list,
2298                                           finger_map_index, trail_id);
2299   return GNUNET_OK;
2300 }
2301
2302
2303 /**
2304  * Core handle for p2p verify successor messages.
2305  * @param cls closure
2306  * @param message message
2307  * @param peer peer identity this notification is about
2308  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
2309  */
2310 static int
2311 handle_dht_p2p_verify_successor(void *cls, const struct GNUNET_PeerIdentity *peer,
2312                                 const struct GNUNET_MessageHeader *message)
2313 {
2314   struct PeerVerifySuccessorMessage *vsm; 
2315   struct GNUNET_PeerIdentity successor;
2316   struct GNUNET_PeerIdentity source_peer;
2317   struct GNUNET_PeerIdentity *next_hop;
2318   struct FriendInfo *target_friend;
2319   //struct FingerInfo *my_predecessor;
2320   //struct GNUNET_PeerIdentity *my_predecessor_trail;
2321   //unsigned int my_predecessor_trail_length;
2322   struct GNUNET_HashCode trail_id;
2323   size_t msize;
2324   
2325   msize = ntohs (message->size);
2326   if (msize != sizeof (struct PeerVerifySuccessorMessage))
2327   {
2328     GNUNET_break_op (0);
2329     return GNUNET_YES;
2330   }
2331   
2332   vsm = (struct PeerVerifySuccessorMessage *) message;
2333   source_peer = vsm->source_peer;
2334   successor = vsm->successor;
2335   trail_id = vsm->trail_id;
2336   
2337   if(0 != (GNUNET_CRYPTO_cmp_peer_identity (&successor, &my_identity)))
2338   {
2339     GNUNET_assert (NULL != (next_hop = 
2340                             GDS_ROUTING_get_next_hop (trail_id, 
2341                                                       GDS_ROUTING_SRC_TO_DEST)));
2342     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2343     GDS_NEIGHBOURS_send_verify_successor_message (source_peer, successor, 
2344                                                   trail_id, target_friend);
2345     return GNUNET_OK;
2346   }
2347 #if 0
2348   my_predecessor = GNUNET_CONTAINER_multihashmap32_get (finger_hashmap, 
2349                                                         PREDECESSOR_FINGER_ID);
2350   if (NULL == my_predecessor) /* FIXME: not sure how to handle this case */
2351     return GNUNET_OK;
2352   
2353   if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&source_peer,
2354                                              &(my_predecessor->finger_identity))))
2355   {
2356     my_predecessor_trail = NULL;
2357     my_predecessor_trail_length = 0;
2358   }
2359   else
2360   {
2361     /* FIXME: copy from my_predecessor trail. now we may have multiple routes
2362      choose the one with shortest length and send that one. */
2363   }
2364   
2365   /* Here you are sending the result back along the trail through which the source
2366    peer send the message to you. now you have to specify the direction such
2367    that the trail id is used but now prev_hop is next_hop. */
2368
2369   GDS_NEIGHBOURS_send_verify_successor_result (source_peer, my_identity,
2370                                                my_predecessor->finger_identity,
2371                                                trail_id,
2372                                                my_predecessor_trail,
2373                                                my_predecessor_trail_length,
2374                                                GDS_ROUTING_DEST_TO_SRC,
2375                                                target_friend);
2376 #endif
2377   return GNUNET_OK;
2378 }
2379
2380
2381 /**
2382  * Core handle for p2p verify successor result messages.
2383  * @param cls closure
2384  * @param message message
2385  * @param peer peer identity this notification is about
2386  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
2387  */
2388 static int
2389 handle_dht_p2p_verify_successor_result(void *cls, const struct GNUNET_PeerIdentity *peer,
2390                                        const struct GNUNET_MessageHeader *message)
2391 {
2392   struct PeerVerifySuccessorResultMessage *vsrm;
2393   enum GDS_ROUTING_trail_direction trail_direction;
2394   struct GNUNET_HashCode trail_id;
2395   unsigned int successor_current_predecessor_trail_length;
2396   struct GNUNET_PeerIdentity *successor_current_predecessor_trail;
2397   struct GNUNET_PeerIdentity destination_peer;
2398   struct GNUNET_PeerIdentity my_new_successor;
2399   struct GNUNET_PeerIdentity *next_hop;
2400   struct FriendInfo *target_friend;
2401   size_t msize;
2402   
2403   msize = ntohs (message->size);
2404   if (msize != sizeof (struct PeerVerifySuccessorResultMessage))
2405   {
2406     GNUNET_break_op (0);
2407     return GNUNET_YES;
2408   }
2409   vsrm = (struct PeerVerifySuccessorResultMessage *) message;
2410   successor_current_predecessor_trail_length = ntohl (vsrm->trail_length);
2411   trail_direction = ntohl (vsrm->trail_direction);
2412   trail_id = vsrm->trail_id;
2413   
2414   if ((msize !=
2415        sizeof (struct PeerVerifySuccessorResultMessage) +
2416        successor_current_predecessor_trail_length * 
2417        sizeof (struct GNUNET_PeerIdentity)) ||
2418        (successor_current_predecessor_trail_length >
2419        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2420   {
2421     GNUNET_break_op (0);
2422     return GNUNET_YES;
2423   }
2424   
2425   successor_current_predecessor_trail = (struct GNUNET_PeerIdentity *) &vsrm[1];
2426   destination_peer = vsrm->destination_peer;
2427   my_new_successor = vsrm->my_predecessor;
2428   
2429   if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&destination_peer, &my_identity)))
2430   {
2431     
2432   }
2433   
2434   next_hop = GDS_ROUTING_get_next_hop (trail_id, trail_direction);
2435   target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop); 
2436   GDS_NEIGHBOURS_send_verify_successor_result (destination_peer, 
2437                                                vsrm->source_successor,
2438                                                my_new_successor, trail_id,
2439                                                successor_current_predecessor_trail,
2440                                                successor_current_predecessor_trail_length,
2441                                                trail_direction, target_friend);
2442   return GNUNET_OK;
2443 }
2444
2445
2446 #if 0
2447 /**
2448  * Adapt it to use trail list array. 
2449  * Core handle for p2p verify successor result messages.
2450  * @param cls closure
2451  * @param message message
2452  * @param peer peer identity this notification is about
2453  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
2454  */
2455 static int
2456 handle_dht_p2p_verify_successor_result(void *cls, const struct GNUNET_PeerIdentity *peer,
2457                                        const struct GNUNET_MessageHeader *message)
2458 {
2459
2460   const struct PeerVerifySuccessorResultMessage *vsrm;
2461   unsigned int trail_length;
2462   struct GNUNET_HashCode trail_id;
2463   struct GNUNET_PeerIdentity *trail;
2464   struct FriendInfo *target_friend;
2465   struct GNUNET_PeerIdentity *next_hop;
2466   struct GNUNET_PeerIdentity destination_peer;
2467   struct GNUNET_PeerIdentity my_new_successor;
2468   struct FingerInfo *current_successor;
2469   struct GNUNET_HashCode old_successor_trail_id;
2470   size_t msize;
2471   
2472   msize = ntohs (message->size);
2473   if (msize < sizeof (struct PeerVerifySuccessorResultMessage))
2474   {
2475     GNUNET_break_op (0);
2476     return GNUNET_YES;
2477   }
2478   vsrm = (const struct PeerVerifySuccessorResultMessage *) message;
2479   trail_length = ntohl (vsrm->trail_length); 
2480   trail_id = vsrm->trail_id;
2481   
2482   if ((msize <
2483        sizeof (struct PeerVerifySuccessorResultMessage) +
2484        trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
2485        (trail_length >
2486        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2487   {
2488     GNUNET_break_op (0);
2489     return GNUNET_YES;
2490   }
2491   
2492   trail = (struct GNUNET_PeerIdentity *) &vsrm[1];
2493   destination_peer = vsrm->destination_peer;
2494   my_new_successor = vsrm->my_predecessor;
2495   
2496   if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&destination_peer, &my_identity)))
2497   {
2498     unsigned int *new_trail_length;
2499     struct GNUNET_PeerIdentity *new_trail;
2500     struct GNUNET_HashCode new_finger_trail_id;
2501     
2502     /* FIXME: generate a new_finger_trail_id */
2503     current_successor = GNUNET_CONTAINER_multihashmap32_get (finger_hashmap, 0);
2504     old_successor_trail_id = current_successor->head->trail_id;
2505     target_friend = 
2506             GNUNET_CONTAINER_multipeermap_get (friend_peermap,
2507                                                &(current_successor->head->head->peer));
2508     
2509     if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_new_successor,
2510                                               &current_successor->finger_identity))
2511     {
2512       *new_trail_length = 0;
2513       new_trail = update_trail_to_new_predecessor (current_successor, 
2514                                                    trail_length, trail,
2515                                                    new_trail_length);
2516      
2517       if (GNUNET_OK == finger_table_add (&my_new_successor, new_trail,
2518                                          new_trail_length , 0, new_finger_trail_id))
2519       {
2520         /*FIXME:
2521          *Here you should send a trail teardown message for old trail id
2522          and trail add for new trail. */
2523       }  
2524       GDS_NEIGHBOURS_send_notify_new_successor (my_identity, my_new_successor,
2525                                                 new_trail, new_trail_length,
2526                                                 new_finger_trail_id, target_friend);
2527     }
2528   }
2529   
2530   next_hop = GDS_ROUTING_get_next_hop (trail_id);
2531   target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop); 
2532   GDS_NEIGHBOURS_send_verify_successor_result (vsrm->destination_peer,
2533                                                vsrm->source_successor,
2534                                                vsrm->my_predecessor,
2535                                                vsrm->trail_id, trail,
2536
2537   return GNUNET_OK;
2538
2539                                                trail_length, target_friend);
2540 #endif
2541
2542                                                
2543 /**
2544  * Core handle for p2p notify new successor messages.
2545  * @param cls closure
2546  * @param message message
2547  * @param peer peer identity this notification is about
2548  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
2549  */
2550 static int
2551 handle_dht_p2p_notify_new_successor(void *cls, const struct GNUNET_PeerIdentity *peer,
2552                                     const struct GNUNET_MessageHeader *message)
2553 {
2554   /* Here we need to pass the whole trail to reach to new successor as we
2555    don't have that stored in our routing table. while passing through each
2556    peer we will have to add an entry. also when you are the destination and
2557    if you have added it back as pred, then you also need to add the trail in 
2558    your own finger table and send add trail message to add this trail. you 
2559    shoudl generate a new trail id. although they are same trails but you have
2560    to ahve different trail id. */
2561   return GNUNET_OK;
2562 }
2563
2564
2565 /**
2566  * FIXME: Here you should keep the trail id with you.
2567  * Core handler for P2P trail rejection message 
2568  * @param cls closure
2569  * @param message message
2570  * @param peer peer identity this notification is about
2571  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
2572  */
2573 static int 
2574 handle_dht_p2p_trail_rejection(void *cls, const struct GNUNET_PeerIdentity *peer,
2575                                const struct GNUNET_MessageHeader *message)
2576 {
2577   struct PeerTrailRejectionMessage *trail_rejection;
2578   unsigned int trail_length;
2579   struct GNUNET_PeerIdentity *trail_peer_list;
2580   struct FriendInfo *target_friend;
2581   struct GNUNET_TIME_Relative congestion_timeout;
2582   struct GNUNET_HashCode trail_id;
2583   struct GNUNET_PeerIdentity next_destination;
2584   struct GNUNET_HashCode new_intermediate_trail_id;
2585   struct GNUNET_PeerIdentity next_peer;
2586   struct GNUNET_PeerIdentity source;
2587   struct GNUNET_PeerIdentity *next_hop;
2588   uint64_t ultimate_destination_finger_value;
2589   unsigned int finger_map_index;
2590   size_t msize;
2591   
2592   msize = ntohs (message->size);
2593   if (msize != sizeof (struct PeerTrailRejectionMessage))
2594   {
2595     GNUNET_break_op (0);
2596     return GNUNET_YES;
2597   }
2598   
2599   trail_rejection = (struct PeerTrailRejectionMessage *) message;
2600   trail_length = ntohl (trail_rejection->trail_length);
2601   
2602   if ((msize != sizeof (struct PeerTrailRejectionMessage) +
2603                trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
2604       (trail_length >
2605        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2606   {
2607     GNUNET_break_op (0);
2608     return GNUNET_YES;
2609   }
2610   
2611   trail_peer_list = (struct GNUNET_PeerIdentity *)&trail_rejection[1];
2612   finger_map_index = ntohl (trail_rejection->finger_map_index);
2613   congestion_timeout = trail_rejection->congestion_time;
2614   source = trail_rejection->source_peer;
2615   trail_id = trail_rejection->trail_id;
2616   ultimate_destination_finger_value = 
2617   trail_rejection->ultimate_destination_finger_identity_value;
2618   
2619   /* First set the congestion time of the friend that sent you this message. */
2620   target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, peer);
2621   target_friend->congestion_duration = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(),
2622                                                                  congestion_timeout);
2623   
2624   if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &source)))
2625   {
2626     return GNUNET_OK;
2627   }
2628   
2629   /* If I am congested then pass this message to peer before me in trail. */
2630   if(GNUNET_YES == GDS_ROUTING_threshold_reached())
2631   {
2632     struct GNUNET_PeerIdentity *new_trail;
2633     unsigned int new_trail_length;
2634     
2635     if (trail_length == 1)
2636     {
2637       new_trail = NULL;
2638       new_trail_length = 0;
2639       next_hop = &source;
2640     }
2641     else 
2642     {
2643       next_hop = &trail_peer_list[trail_length - 2];
2644       /* Remove myself from the trail. */
2645       new_trail_length = trail_length -1;
2646       new_trail = GNUNET_malloc (new_trail_length * sizeof (struct GNUNET_PeerIdentity));
2647       memcpy (new_trail, trail_peer_list, new_trail_length * sizeof (struct GNUNET_PeerIdentity));
2648     }
2649     
2650     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2651     GDS_NEIGHBOURS_send_trail_rejection (source, 
2652                                          ultimate_destination_finger_value,
2653                                          my_identity, finger_map_index,
2654                                          new_trail,new_trail_length,trail_id,
2655                                          target_friend, CONGESTION_TIMEOUT);
2656     return GNUNET_YES;
2657   }
2658   
2659   /* Look for next_hop to pass the trail setup message */
2660   next_hop = find_successor (ultimate_destination_finger_value, 
2661                              &next_destination,
2662                              &new_intermediate_trail_id,
2663                              finger_map_index);
2664   
2665   if (0 == (GNUNET_CRYPTO_cmp_peer_identity (next_hop, &my_identity)))/* This means I am the final destination */
2666   {
2667     if (0 == trail_length)
2668       next_peer = source;
2669     else
2670       next_peer = trail_peer_list[trail_length-1];
2671     
2672     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_peer);
2673     GDS_NEIGHBOURS_send_trail_setup_result (source,
2674                                             my_identity,
2675                                             target_friend, trail_length,
2676                                             trail_peer_list,
2677                                             finger_map_index, trail_id);
2678   }
2679   else
2680   {
2681     struct GNUNET_PeerIdentity peer_list[trail_length + 1];
2682     
2683     memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
2684     peer_list[trail_length] = my_identity;
2685     
2686     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2687     GDS_NEIGHBOURS_send_trail_setup (source,
2688                                      ultimate_destination_finger_value,
2689                                      next_destination, 
2690                                      target_friend, trail_length + 1, peer_list, 
2691                                      finger_map_index, trail_id,
2692                                      new_intermediate_trail_id);
2693   }
2694   return GNUNET_OK;
2695 }
2696
2697
2698 /*
2699  * Core handle for p2p trail tear down messages.
2700  * @param cls closure
2701  * @param message message
2702  * @param peer peer identity this notification is about
2703  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
2704  */
2705 static int 
2706 handle_dht_p2p_trail_compression (void *cls, const struct GNUNET_PeerIdentity *peer,
2707                                const struct GNUNET_MessageHeader *message)
2708 {
2709   struct PeerTrailCompressionMessage *trail_compression;
2710   struct GNUNET_PeerIdentity *next_hop;
2711   struct GNUNET_HashCode trail_id;
2712   struct FriendInfo *target_friend;
2713   size_t msize;
2714   
2715   msize = ntohs (message->size);
2716   if (msize != sizeof (struct PeerTrailCompressionMessage))
2717   {
2718     GNUNET_break_op (0);
2719     return GNUNET_OK;
2720   }
2721   
2722   trail_compression = (struct PeerTrailCompressionMessage *) message;
2723   trail_id = trail_compression->trail_id;
2724   
2725   if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_compression->new_first_friend),
2726                                              &my_identity)))
2727   {
2728      if(0 != (GNUNET_CRYPTO_cmp_peer_identity (&(trail_compression->destination_peer), 
2729                                                &my_identity)))
2730      {
2731        GDS_ROUTING_update_trail_prev_hop (trail_id, 
2732                                           trail_compression->source_peer);
2733      }
2734      return GNUNET_OK;
2735   }
2736   
2737   next_hop = GDS_ROUTING_get_next_hop (trail_id, GDS_ROUTING_SRC_TO_DEST);
2738   if (NULL == next_hop)
2739   {
2740     GNUNET_break (0); /*FIXME: How to handle this case.  */
2741     return GNUNET_OK;
2742   }
2743   GNUNET_assert (GNUNET_YES == GDS_ROUTING_remove_trail (trail_id));
2744   target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2745   GDS_NEIGHBOURS_send_trail_compression (trail_compression->source_peer, 
2746                                          trail_compression->destination_peer,
2747                                          trail_id,
2748                                          trail_compression->new_first_friend,
2749                                          target_friend);
2750   return GNUNET_OK;
2751 }
2752
2753
2754 /**
2755  * Core handler for trail teardown message. 
2756  * @param cls closure
2757  * @param message message
2758  * @param peer peer identity this notification is about
2759  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
2760  */
2761 static int 
2762 handle_dht_p2p_trail_teardown (void *cls, const struct GNUNET_PeerIdentity *peer,
2763                                const struct GNUNET_MessageHeader *message)
2764 {
2765   return GNUNET_OK;
2766 }
2767
2768
2769 /**
2770  * TRAIL ID and each peer should add an entry in the routing table. 
2771  * Core handle for p2p add trail message. 
2772  * @param cls closure
2773  * @param message message
2774  * @param peer peer identity this notification is about
2775  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
2776  */
2777 static int 
2778 handle_dht_p2p_add_trail (void *cls, const struct GNUNET_PeerIdentity *peer,
2779                           const struct GNUNET_MessageHeader *message)
2780 {
2781   return GNUNET_OK;  
2782 }
2783
2784
2785 /**
2786  *FIXME; call send_trail_teardown_message on all the trails of the finger that
2787  * you remove. Also you don't need to decerement friend trail count as that
2788  * friend is removed. But you can not send trail teardown message as the friend
2789  * is disconnected. then you don't have any next_hop. and in case there are 
2790  * multiple trails. and friend is the first trail then you remove only the trail.  
2791  * Iterate over finger_hashmap, and remove entries if finger is the disconnected
2792  * peer or if disconnected peer is the first friend in the trail to reach the
2793  * finger. 
2794  * @param cls closure
2795  * @param key current public key
2796  * @param value value in the hash map
2797  * @return #GNUNET_YES if we should continue to
2798  *         iterate,
2799  *         #GNUNET_NO if not.
2800  */
2801 static int
2802 remove_matching_finger (void *cls,
2803                         uint32_t key,
2804                         void *value)
2805 {
2806   struct FingerInfo *remove_finger = value;
2807   const struct GNUNET_PeerIdentity *disconnected_peer = cls;
2808   struct TrailList *trail_list;
2809   int i;
2810   
2811   if (0 == GNUNET_CRYPTO_cmp_peer_identity (&remove_finger->finger_identity,
2812                                             disconnected_peer))
2813   {
2814     GNUNET_assert (GNUNET_YES ==
2815                    GNUNET_CONTAINER_multihashmap32_remove (finger_hashmap,
2816                                                          key, 
2817                                                          remove_finger));
2818     free_finger (remove_finger);
2819     return GNUNET_YES;
2820   }
2821   
2822   for (i = 0; i< remove_finger->trails_count; i++)
2823   {
2824     trail_list = &remove_finger->trail_list[i];  
2825     if (0 == GNUNET_CRYPTO_cmp_peer_identity (&trail_list->trail_head->peer,
2826                                                 disconnected_peer))
2827     {
2828       GNUNET_assert (GNUNET_YES ==
2829                      GNUNET_CONTAINER_multihashmap32_remove (finger_hashmap,
2830                                                            key, 
2831                                                            remove_finger));
2832        free_finger (remove_finger);
2833     }
2834   }
2835   
2836   return GNUNET_YES;
2837 }
2838
2839
2840 /**
2841  * Method called whenever a peer disconnects.
2842  *
2843  * @param cls closure
2844  * @param peer peer identity this notification is about
2845  */
2846 static void
2847 handle_core_disconnect (void *cls,
2848                                           const struct GNUNET_PeerIdentity *peer)
2849 {
2850   struct FriendInfo *remove_friend;
2851   
2852   if (0 == memcmp (&my_identity, peer, sizeof (struct GNUNET_PeerIdentity)))
2853     return;
2854
2855   remove_friend =
2856       GNUNET_CONTAINER_multipeermap_get (friend_peermap, peer);
2857   
2858   if (NULL == remove_friend)
2859   {
2860     GNUNET_break (0);
2861     return;
2862   }
2863   
2864   GNUNET_assert (GNUNET_SYSERR != 
2865                  GNUNET_CONTAINER_multihashmap32_iterate (finger_hashmap,
2866                                                           &remove_matching_finger,
2867                                                           (void *)peer));
2868   GDS_ROUTING_remove_trail_by_peer (peer);
2869   GNUNET_assert (GNUNET_YES ==
2870                  GNUNET_CONTAINER_multipeermap_remove (friend_peermap,
2871                                                        peer,
2872                                                        remove_friend));
2873   
2874   if (0 != GNUNET_CONTAINER_multipeermap_size (friend_peermap))
2875     return;
2876   
2877   if (GNUNET_SCHEDULER_NO_TASK != find_finger_trail_task)
2878   {
2879       GNUNET_SCHEDULER_cancel (find_finger_trail_task);
2880       find_finger_trail_task = GNUNET_SCHEDULER_NO_TASK;
2881   }
2882   else
2883     GNUNET_break (0);
2884 }
2885
2886
2887 /**
2888  * Method called whenever a peer connects.
2889  *
2890  * @param cls closure
2891  * @param peer_identity peer identity this notification is about
2892  */
2893 static void
2894 handle_core_connect (void *cls, const struct GNUNET_PeerIdentity *peer_identity)
2895 {
2896   struct FriendInfo *friend;
2897
2898   /* Check for connect to self message */
2899   if (0 == memcmp (&my_identity, peer_identity, sizeof (struct GNUNET_PeerIdentity)))
2900     return;
2901   
2902   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected to %s\n", GNUNET_i2s (peer_identity));
2903   
2904   /* If peer already exists in our friend_peermap, then exit. */
2905   if (GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains (friend_peermap, peer_identity))
2906   {
2907     GNUNET_break (0);
2908     return;
2909   }
2910   
2911   GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# peers connected"), 1,
2912                             GNUNET_NO);
2913
2914   friend = GNUNET_new (struct FriendInfo);
2915   friend->id = *peer_identity;
2916   
2917   GNUNET_assert (GNUNET_OK ==
2918                  GNUNET_CONTAINER_multipeermap_put (friend_peermap,
2919                                                     peer_identity, friend,
2920                                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
2921
2922   /* got a first connection, good time to start with FIND FINGER TRAIL requests... */
2923   if (GNUNET_SCHEDULER_NO_TASK == find_finger_trail_task)
2924     find_finger_trail_task = GNUNET_SCHEDULER_add_now (&send_find_finger_trail_message, NULL);
2925 }
2926
2927
2928 /**
2929  * To be called on core init/fail.
2930  *
2931  * @param cls service closure
2932  * @param identity the public identity of this peer
2933  */
2934 static void
2935 core_init (void *cls,
2936            const struct GNUNET_PeerIdentity *identity)
2937 {
2938   my_identity = *identity;
2939 }
2940
2941
2942 /**
2943  * Initialize neighbours subsystem.
2944  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
2945  */
2946 int
2947 GDS_NEIGHBOURS_init (void)
2948 {
2949   static struct GNUNET_CORE_MessageHandler core_handlers[] = {
2950     {&handle_dht_p2p_put, GNUNET_MESSAGE_TYPE_DHT_P2P_PUT, 0},
2951     {&handle_dht_p2p_get, GNUNET_MESSAGE_TYPE_DHT_P2P_GET, 0},
2952     {&handle_dht_p2p_get_result, GNUNET_MESSAGE_TYPE_DHT_P2P_GET_RESULT, 0},   
2953     {&handle_dht_p2p_trail_setup, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP, 0},
2954     {&handle_dht_p2p_trail_setup_result, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP_RESULT, 0},
2955     {&handle_dht_p2p_verify_successor, GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR, 0},
2956     {&handle_dht_p2p_verify_successor_result, GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR_RESULT, 0},
2957     {&handle_dht_p2p_notify_new_successor, GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_NEW_SUCCESSOR, 0},
2958     {&handle_dht_p2p_trail_rejection, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_REJECTION, 0},
2959     {&handle_dht_p2p_trail_compression, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_COMPRESSION, 0},
2960     {&handle_dht_p2p_trail_teardown, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_TEARDOWN, 0},
2961     {&handle_dht_p2p_add_trail, GNUNET_MESSAGE_TYPE_DHT_P2P_ADD_TRAIL, 0},
2962     {NULL, 0, 0}
2963   };
2964   
2965   core_api =
2966     GNUNET_CORE_connect (GDS_cfg, NULL, &core_init, &handle_core_connect,
2967                          &handle_core_disconnect, NULL, GNUNET_NO, NULL,
2968                          GNUNET_NO, core_handlers);
2969   if (NULL == core_api)
2970     return GNUNET_SYSERR;
2971   
2972   friend_peermap = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_NO);
2973   finger_hashmap = GNUNET_CONTAINER_multihashmap32_create (MAX_FINGERS * 4/3);
2974   
2975   return GNUNET_OK;
2976 }
2977
2978 /**
2979  * Shutdown neighbours subsystem.
2980  */
2981 void
2982 GDS_NEIGHBOURS_done (void)
2983 {
2984   if (NULL == core_api)
2985     return;
2986   
2987   GNUNET_CORE_disconnect (core_api);
2988   core_api = NULL;
2989   
2990   GNUNET_assert (0 == GNUNET_CONTAINER_multipeermap_size (friend_peermap));
2991   GNUNET_CONTAINER_multipeermap_destroy (friend_peermap);
2992   friend_peermap = NULL;
2993   
2994   GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap32_size (finger_hashmap));
2995   GNUNET_CONTAINER_multihashmap32_destroy (finger_hashmap);
2996   finger_hashmap = NULL;
2997
2998   if (GNUNET_SCHEDULER_NO_TASK != find_finger_trail_task)
2999   {
3000     GNUNET_break (0);
3001     GNUNET_SCHEDULER_cancel (find_finger_trail_task);
3002     find_finger_trail_task = GNUNET_SCHEDULER_NO_TASK;
3003   }
3004 }
3005
3006
3007 /**
3008  * Get my identity
3009  *
3010  * @return my identity
3011  */
3012 struct GNUNET_PeerIdentity 
3013 GDS_NEIGHBOURS_get_my_id (void)
3014 {
3015   return my_identity;
3016 }