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