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