- Modified find_successor
[oweals/gnunet.git] / src / dht / gnunet-service-xdht_neighbours.c
1 /*
2      This file is part of GNUnet.
3      (C) 2009-2013 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
52 /* FIXME:
53  1. Add content and route replication later. 
54  *2. Algorithm to shorten the trail length - one possible solution could be
55  * when we are in trail seutp result part. each peer in the trail check if any of
56  * the corresponding peers is its friend list. Then it can shortcut the path.
57  * But this will have O(n) run time at each peer, where n = trail_length.\
58  * or rather O(n)+O(n-1)+..O(1) =O(n). 
59  * 4. As we start looking for finger from i = 0, using this parameter to 
60  * generate random value does not look smart in send_find_finger_trail_message. 
61  * 6. Need to add a new task, fix fingers. For node join/leave, we need to 
62  * upgrade our finger table periodically. So, we should call fix_fingers 
63  * and change our finger table. 
64  * 7. Should we look for fingers one by one in send_find_finger_trail_setup
65  * 8. Change the message is gnunet_protocols.h 
66  */
67
68
69 /**
70  * Maximum possible fingers of a peer.
71  * FIXME: Should it be 64 as we are doing all the operation on 64 bit numbers now? 
72  */
73 #define MAX_FINGERS 64
74
75 /**
76  * Maximum allowed number of pending messages per friend peer.
77  */
78 #define MAXIMUM_PENDING_PER_FRIEND 64
79
80 /**
81  * How long at least to wait before sending another find finger trail request.
82  */
83 #define DHT_MINIMUM_FIND_FINGER_TRAIL_INTERVAL GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 30)
84
85 /**
86  * How long at most to wait before sending another find finger trail request.
87  */
88 #define DHT_MAXIMUM_FIND_FINGER_TRAIL_INTERVAL GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 10)
89
90 /**
91  * FIXME: Currently used in GDS_NEIGHBOURS_handle_trail_setup.
92  * I have just copied it from gnunet-service-dht_neighbours. Will it work here? 
93  * How long at most to wait for transmission of a GET request to another peer?
94  */
95 #define GET_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2)
96
97 GNUNET_NETWORK_STRUCT_BEGIN
98
99 /* FIXME:
100  * 1) Bloomfilter is not required for X-Vine.
101  * Keep the field now but remove it when implementing PUT/GET.
102  * 2) also, check the field of put/get/result if all are required for
103  * x-vine or not. */
104   
105 /**
106  * P2P PUT message
107  */
108 struct PeerPutMessage
109 {
110   /**
111    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_PUT
112    */
113   struct GNUNET_MessageHeader header;
114
115   /**
116    * Processing options
117    */
118   uint32_t options GNUNET_PACKED;
119
120   /**
121    * Content type.
122    */
123   uint32_t type GNUNET_PACKED;
124
125   /**
126    * Hop count
127    */
128   uint32_t hop_count GNUNET_PACKED;
129
130   /**
131    * Replication level for this message
132    */
133   uint32_t desired_replication_level GNUNET_PACKED;
134
135   /**
136    * Length of the PUT path that follows (if tracked).
137    */
138   uint32_t put_path_length GNUNET_PACKED;
139
140   /**
141    * When does the content expire?
142    */
143   struct GNUNET_TIME_AbsoluteNBO expiration_time;
144
145   /**
146    * Bloomfilter (for peer identities) to stop circular routes
147    */
148   char bloomfilter[DHT_BLOOM_SIZE];
149
150   /**
151    * The key we are storing under.
152    */
153   struct GNUNET_HashCode key;
154
155   /* put path (if tracked) */
156
157   /* Payload */
158
159 };
160
161
162 /**
163  * P2P Result message
164  */
165 struct PeerResultMessage
166 {
167   /**
168    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT
169    */
170   struct GNUNET_MessageHeader header;
171
172   /**
173    * Content type.
174    */
175   uint32_t type GNUNET_PACKED;
176
177   /**
178    * Length of the PUT path that follows (if tracked).
179    */
180   uint32_t put_path_length GNUNET_PACKED;
181
182   /**
183    * Length of the GET path that follows (if tracked).
184    */
185   uint32_t get_path_length GNUNET_PACKED;
186
187   /**
188    * When does the content expire?
189    */
190   struct GNUNET_TIME_AbsoluteNBO expiration_time;
191
192   /**
193    * The key of the corresponding GET request.
194    */
195   struct GNUNET_HashCode key;
196
197   /* put path (if tracked) */
198
199   /* get path (if tracked) */
200
201   /* Payload */
202
203 };
204
205
206 /**
207  * P2P GET message
208  */
209 struct PeerGetMessage
210 {
211   /**
212    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_GET
213    */
214   struct GNUNET_MessageHeader header;
215
216   /**
217    * Processing options
218    */
219   uint32_t options GNUNET_PACKED;
220
221   /**
222    * Desired content type.
223    */
224   uint32_t type GNUNET_PACKED;
225
226   /**
227    * Hop count
228    */
229   uint32_t hop_count GNUNET_PACKED;
230
231   /**
232    * Desired replication level for this request.
233    */
234   uint32_t desired_replication_level GNUNET_PACKED;
235
236   /**
237    * Size of the extended query.
238    */
239   uint32_t xquery_size;
240
241   /**
242    * Bloomfilter mutator.
243    */
244   uint32_t bf_mutator;
245
246   /**
247    * Bloomfilter (for peer identities) to stop circular routes
248    */
249   char bloomfilter[DHT_BLOOM_SIZE];
250
251   /**
252    * The key we are looking for.
253    */
254   struct GNUNET_HashCode key;
255
256 };
257
258
259 /**
260  * A destination can be either a friend or finger.
261  */
262 enum current_destination_type
263 {
264   /* Friend */
265   FRIEND ,
266   
267   /* Finger */
268   FINGER ,
269
270   /* My own identity */
271   MY_ID        
272 };
273
274 /**
275  * P2P Trail setup message
276  * TODO: Take reference from put_path and get_path to understand how to use size of trail list.  
277  */
278 struct PeerTrailSetupMessage
279 {
280   /**
281    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP
282    */
283   struct GNUNET_MessageHeader header;
284
285   /**
286    * Source peer which wants to find trail to one of its finger. 
287    */
288   struct GNUNET_PeerIdentity source_peer;
289
290   /**
291    * As we are not sending any hello messages to this destination
292    * finger, we are only searching for it, we can just send 64 bit. 
293    * Finger id to which we want to set up the trail to. 
294    *
295   struct GNUNET_PeerIdentity destination_finger; */
296
297   /**
298    * Finger id to which we want to set up the trail to. 
299    */
300   uint64_t destination_finger;
301   
302   /**
303    * If set to 1, then we are looking for trail to our immediate successor. 
304    */
305   unsigned int successor_flag;
306   
307   /**
308    * If the message is forwarded to finger or friend. 
309    */
310   enum current_destination_type current_destination_type;
311   
312   /**
313    * This field contains the peer to which this packet is forwarded.
314    */
315   struct GNUNET_PeerIdentity current_destination;
316  
317   /**
318    * Number of entries in trail list.
319    * FIXME: Is this data type correct?
320    * FIMXE: Is usage of GNUNET_PACKED correct?
321    */
322   uint32_t trail_length GNUNET_PACKED;
323   
324   /* FIXME: Add this field later. 
325    * The finger index in finger map. 
326   unsigned int finger_index;*/
327   
328 };
329
330 /**
331  *
332  */
333 struct PeerVerifySuccessor
334 {
335   
336 };
337
338
339 /**
340  *
341  */
342 struct PeerVerifySuccessorResult
343 {
344   
345 };
346
347 /**
348  *
349  */
350 struct PeerNotifyNewSuccessor
351 {
352   
353 };
354 /**
355  * P2P Trail setup Result message
356  */
357 struct PeerTrailSetupResultMessage
358 {
359   /**
360    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_RESULT_SETUP
361    */
362   struct GNUNET_MessageHeader header;
363   
364   /**
365    * Finger to which we have found the path. 
366    */
367   struct GNUNET_PeerIdentity finger;
368
369   /**
370    * Peer which was looking for the trail to finger. 
371    */
372   struct GNUNET_PeerIdentity destination_peer;
373
374   /**
375    * This field contains the peer to which this packet is forwarded.
376    */
377   struct GNUNET_PeerIdentity current_destination;
378   
379   /**
380    * FIXME: Temporary field used to remember at which index we should read
381    * to get our next peer. 
382    */
383   unsigned int current_index;
384   
385   /**
386    * If set to 1, then this trail is the trail to succcessor of our finger. 
387    */
388   unsigned int successor_flag;
389   
390   /**
391    * Number of entries in trail list.
392    * FIXME: Is this data type correct?
393    * FIXME: Is usage of GNUNET_PACKED correct?
394    */
395   uint32_t trail_length GNUNET_PACKED;
396   
397 };
398
399 GNUNET_NETWORK_STRUCT_END
400
401
402 /**
403  * Linked list of messages to send to a particular other peer.
404  */
405 struct P2PPendingMessage
406 {
407   /**
408    * Pointer to next item in the list
409    */
410   struct P2PPendingMessage *next;
411
412   /**
413    * Pointer to previous item in the list
414    */
415   struct P2PPendingMessage *prev;
416
417   /**
418    * When does this message time out?
419    */
420   struct GNUNET_TIME_Absolute timeout;
421
422    /**
423    * Message importance level.  FIXME: used? useful?
424    */
425   unsigned int importance;
426
427   /**
428    * Actual message to be sent, allocated at the end of the struct:
429    * // msg = (cast) &pm[1];
430    * // memcpy (&pm[1], data, len);
431    */
432   const struct GNUNET_MessageHeader *msg;
433
434 };
435
436
437  /**
438   * Linked List of peers which are part of trail to reach a particular Finger.
439   */
440 struct TrailPeerList
441 {
442    /**
443    * Pointer to next item in the list
444    */
445    struct TrailPeerList *next;
446
447    /**
448    * Pointer to previous item in the list
449    */
450    struct TrailPeerList *prev;
451    
452    /**
453     * An element in this trail list
454     */
455    struct GNUNET_PeerIdentity peer;
456   
457 };
458
459
460 /**
461  *  Entry in friend_peermap.
462  */
463 struct FriendInfo
464 {
465   /**
466    * What is the identity of the peer?
467    */
468   struct GNUNET_PeerIdentity id;
469
470   /**
471    * Count of outstanding messages for peer.
472    */
473   unsigned int pending_count;
474   
475   /**
476    * Successor of this finger.
477    */
478   struct GNUNET_PeerIdentity successor_identity;
479   
480   /**
481    * Predecessor of this finger.
482    */
483   struct GNUNET_PeerIdentity predecessor_identity;
484   
485   /**
486    * Head of pending messages to be sent to this peer.
487    */
488  struct P2PPendingMessage *head;
489
490  /**
491   * Tail of pending messages to be sent to this peer.
492   */
493  struct P2PPendingMessage *tail;
494  
495  /**
496   * TODO - How and where to use this?
497   * Core handle for sending messages to this peer.
498   */
499  struct GNUNET_CORE_TransmitHandle *th;
500
501 };
502
503
504 /**
505  * FIXME: As in chord , where we store the actual finger identity we were looking
506  * for and the real id which we got as successor. If we want to store like that 
507  * then we will need to add a new field and search actual peer id. 
508  * FIXME: Should we use another PeerIdentity which is smaller
509  * than 256 bits while storing. 
510  * SUPU
511  * finger_identity is the actual finger that we were looking for.
512  * successor is the peer id which is our finger in place of finger_identity
513  * that we were actually looking for. It may happen that finger_identity
514  * was not in the network and we found the successor closest to that
515  * finger_identity.
516  * Predcessor is needed in case of node join/fail. 
517  * Entry in finger_peermap.
518  */
519 struct FingerInfo
520 {
521   /**
522    * Finger identity.
523    */
524   struct GNUNET_PeerIdentity finger_identity;
525   
526   /**
527    * If 1, then this finger entry is first finger /successor of the peer.
528    */
529   unsigned int successor;
530   /**
531    * List of peers in the trail.
532    */
533   const struct GNUNET_PeerIdentity *trail_peer_list;
534 };
535
536 /**
537  * Task that sends FIND FINGER TRAIL requests.
538  */
539 static GNUNET_SCHEDULER_TaskIdentifier find_finger_trail_task;
540
541 /**
542  * FIXME: As we should check for our immediate successor
543  * in case of node join/fail, the immediate successor will change. 
544  * Hence we define a process which will be scheduled in regular interval.
545  * But you should schedule this process once you have found your successor.
546  * so, in finger_table_add_entry, when finger_peermap is size 1 then start
547  * this task, and periodically call it within it self like find_finger_trail_setup
548  * 
549  * Task that periodically checks for the immediate successor. 
550  */
551 static GNUNET_SCHEDULER_TaskIdentifier verify_successor;
552
553 /**
554  * Identity of this peer.
555  */
556 static struct GNUNET_PeerIdentity my_identity;
557
558 /**
559  * FIXME: Not used anywhere in the code yet. 
560  * Hash of the identity of this peer.
561  */
562 static struct GNUNET_HashCode my_identity_hash;
563
564 /**
565  * Hash map of all the friends of a peer
566  */
567 static struct GNUNET_CONTAINER_MultiPeerMap *friend_peermap;
568
569 /**
570  * Hash map of all the fingers of a peer
571  */
572 static struct GNUNET_CONTAINER_MultiPeerMap *finger_peermap;
573
574 /**
575  * TODO: Ask whats the use of ATS.
576  * Handle to ATS.
577  */
578 static struct GNUNET_ATS_PerformanceHandle *atsAPI;
579
580 /**
581  * Handle to CORE.
582  */
583 static struct GNUNET_CORE_Handle *core_api;
584
585 /**
586  * The current finger index that we have found trail to.
587  */
588 static unsigned int current_finger_index;
589
590
591 /**
592  * Called when core is ready to send a message we asked for
593  * out to the destination.
594  *
595  * @param cls the 'struct PeerInfo' of the target peer
596  * @param size number of bytes available in buf
597  * @param buf where the callee should write the message
598  * @return number of bytes written to buf
599  */
600 static size_t
601 core_transmit_notify (void *cls, size_t size, void *buf)
602 {
603   struct FriendInfo *peer = cls;
604   char *cbuf = buf;
605   struct P2PPendingMessage *pending;
606   size_t off;
607   size_t msize;
608   
609   peer->th = NULL;
610   while ((NULL != (pending = peer->head)) &&
611          (0 == GNUNET_TIME_absolute_get_remaining (pending->timeout).rel_value_us))
612   {
613     peer->pending_count--;
614     GNUNET_CONTAINER_DLL_remove (peer->head, peer->tail, pending);  
615     GNUNET_free (pending);
616   }
617   if (NULL == pending)
618   {
619     /* no messages pending */
620     return 0;
621   }
622   if (NULL == buf)
623   {
624     peer->th =
625         GNUNET_CORE_notify_transmit_ready (core_api, GNUNET_NO,
626                                            GNUNET_CORE_PRIO_BEST_EFFORT,
627                                            GNUNET_TIME_absolute_get_remaining
628                                            (pending->timeout), &peer->id,
629                                            ntohs (pending->msg->size),
630                                            &core_transmit_notify, peer);
631     GNUNET_break (NULL != peer->th);
632     return 0;
633   }
634   off = 0;
635   while ((NULL != (pending = peer->head)) &&
636          (size - off >= (msize = ntohs (pending->msg->size))))
637   {
638     GNUNET_STATISTICS_update (GDS_stats,
639                               gettext_noop
640                               ("# Bytes transmitted to other peers"), msize,
641                               GNUNET_NO);
642     memcpy (&cbuf[off], pending->msg, msize);
643     off += msize;
644     peer->pending_count--;
645     GNUNET_CONTAINER_DLL_remove (peer->head, peer->tail, pending);
646     GNUNET_free (pending);
647   }
648   if (peer->head != NULL)
649   {
650     peer->th =
651         GNUNET_CORE_notify_transmit_ready (core_api, GNUNET_NO,
652                                            GNUNET_CORE_PRIO_BEST_EFFORT,
653                                            GNUNET_TIME_absolute_get_remaining
654                                            (pending->timeout), &peer->id, msize,
655                                            &core_transmit_notify, peer);
656     GNUNET_break (NULL != peer->th);
657   }
658   return off;
659 }
660
661
662 /**
663  * Transmit all messages in the friend's message queue.
664  *
665  * @param peer message queue to process
666  */
667 static void
668 process_friend_queue (struct FriendInfo *peer)
669 {
670   struct P2PPendingMessage *pending;
671   
672   if (NULL == (pending = peer->head))
673     return;
674   if (NULL != peer->th)
675     return;
676   
677   GNUNET_STATISTICS_update (GDS_stats,
678                             gettext_noop
679                             ("# Bytes of bandwidth requested from core"),
680                             ntohs (pending->msg->size), GNUNET_NO);
681   
682   /* FIXME: Are we correctly initializing importance and pending. */
683   peer->th =
684       GNUNET_CORE_notify_transmit_ready (core_api, GNUNET_NO,
685                                          pending->importance,
686                                          GNUNET_TIME_absolute_get_remaining
687                                          (pending->timeout), &peer->id,
688                                          ntohs (pending->msg->size),
689                                          &core_transmit_notify, peer);
690   GNUNET_break (NULL != peer->th);
691 }
692
693
694 /**
695  * SUPU:
696  * We add the next destination i.e. friend to which we are sending the packet
697  * to our peer list in the calling function and we also increment trail_length
698  * in calling function i.e. send_find_finger_trail and handle_dht_p2p_trail_setup.
699  * Here we only copy the whole trail into our peer_list. 
700  * Setup the trail message and forward it to a friend. 
701  * @param source_peer Peer which wants to set up the trail to one of its finger.
702  * @param destination_finger Peer to which we want to set up the trail to.
703  * @param current_destination Current peer to which this message should be forwarded.
704  * @param trail_length Numbers of peers in the trail.
705  * @param trail_peer_list peers this request has traversed so far
706  * @param successor_flag If 1 then we are looking for trail to our successor. 
707  */
708 void
709 GDS_NEIGHBOURS_handle_trail_setup(struct GNUNET_PeerIdentity *source_peer,
710                                   uint64_t *destination_finger,
711                                   struct FriendInfo *current_destination,
712                                   unsigned int trail_length,
713                                   struct GNUNET_PeerIdentity *trail_peer_list,
714                                   unsigned int successor_flag)
715 {
716   struct P2PPendingMessage *pending;
717   struct PeerTrailSetupMessage *tsm;
718   struct GNUNET_PeerIdentity *peer_list;
719   size_t msize;
720   
721   msize = sizeof(struct PeerTrailSetupMessage) + 
722           (trail_length * sizeof(struct GNUNET_PeerIdentity));
723   
724   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
725   {
726     GNUNET_break (0);
727     return;
728   }
729   
730   if (current_destination->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
731   {  
732     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
733                                 1, GNUNET_NO);
734   }
735     
736   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
737   pending->importance = 0;    /* FIXME */
738   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
739   tsm = (struct PeerTrailSetupMessage *) &pending[1]; 
740   pending->msg = &tsm->header;
741   tsm->header.size = htons (msize);
742   tsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP);
743   memcpy(&(tsm->destination_finger), destination_finger, sizeof (uint64_t)); //FIXME: Is this copy correct?
744   memcpy(&(tsm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
745   memcpy(&(tsm->current_destination),&(current_destination->id), sizeof (struct GNUNET_PeerIdentity));
746   tsm->current_destination_type = htonl(FRIEND); 
747   tsm->trail_length = htonl(trail_length); 
748   if(successor_flag == 1)
749     tsm->successor_flag = 1;
750   peer_list = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * trail_length); 
751   peer_list = (struct GNUNET_PeerIdentity *) &tsm[1];
752   memcpy(peer_list, trail_peer_list, trail_length * sizeof(struct GNUNET_PeerIdentity));
753   
754   GNUNET_CONTAINER_DLL_insert_tail (current_destination->head, current_destination->tail, pending);
755   current_destination->pending_count++;
756   process_friend_queue (current_destination);
757   
758 }
759
760 /**
761  * Handle a tail setup result message. 
762  * @param destination_peer Peer which will get the trail to one of its finger.
763  * @param source_finger Peer to which the trail has been setup to.
764  * @param current_destination Current peer to which this message should be forwarded.
765  * @param trail_length Numbers of peers in the trail.
766  * @param trail_peer_list peers this request has traversed so far 
767  * @param current_trail_index Index in trail_peer_list. 
768  */
769 void
770 GDS_NEIGHBOURS_handle_trail_setup_result(struct GNUNET_PeerIdentity *destination_peer,
771                                   struct GNUNET_PeerIdentity *source_finger,
772                                   struct FriendInfo *current_destination,
773                                   unsigned int trail_length,
774                                   const struct GNUNET_PeerIdentity *trail_peer_list,
775                                   unsigned int current_trial_index,
776                                   unsigned int successor_flag)
777 {
778   struct P2PPendingMessage *pending;
779   struct PeerTrailSetupResultMessage *tsrm;
780   struct GNUNET_PeerIdentity *peer_list;
781   size_t msize;
782   
783   msize = sizeof(struct PeerTrailSetupMessage) + 
784           (trail_length * sizeof(struct GNUNET_PeerIdentity));
785   
786   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
787   {
788     GNUNET_break (0);
789     return;
790   }
791   
792   if (current_destination->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
793   {  
794     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
795                                 1, GNUNET_NO);
796   }
797
798   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
799   pending->importance = 0;    /* FIXME */
800   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
801   tsrm = (struct PeerTrailSetupResultMessage *) &pending[1]; 
802   pending->msg = &tsrm->header;
803   tsrm->header.size = htons (msize);
804   tsrm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP_RESULT);
805   memcpy(&(tsrm->current_destination), &(current_destination->id), sizeof(struct GNUNET_PeerIdentity));
806   memcpy(&(tsrm->destination_peer), destination_peer, sizeof(struct GNUNET_PeerIdentity));
807   memcpy(&(tsrm->finger), source_finger, sizeof(struct GNUNET_PeerIdentity));
808   tsrm->trail_length = htonl(trail_length);
809   tsrm->current_index = htonl(current_trial_index);
810   tsrm->successor_flag = htonl(successor_flag);
811   peer_list = (struct GNUNET_PeerIdentity *) &tsrm[1];
812   memcpy(peer_list, trail_peer_list, trail_length * sizeof(struct GNUNET_PeerIdentity));
813   
814   /* Send the message to chosen friend. */
815   GNUNET_CONTAINER_DLL_insert_tail (current_destination->head, current_destination->tail, pending);
816   current_destination->pending_count++;
817   process_friend_queue (current_destination);
818 }
819
820
821 /**
822  * This function is called from send_verify_successor_message funciton
823  * and handle_dht_p2p_verify_successor. 
824  * Construct a PeerVerifySuccessor message and send it to friend.
825  */
826 void GDS_NEIGUBOURS_handle_verify_successor()
827 {
828   /* In this funciton, you receive 
829    1. successor
830    2. trial to reach that successor
831    3. trail_length.
832    4. current trail index --> this gives the next_hop on whose pending queue you should
833    add the message. */
834 }
835
836
837 /**
838  * this function will be called by destination successor. 
839  * Construct a PeerVerifySuccessorResult message and send it to friend.
840  */
841 void GDS_NEIGHBOURS_handle_verify_successor_result()
842 {
843   /* In this funciton, you receive 
844    1. successor
845    2. trial to reach that successor
846    3. trail_length.
847    4. current trail index --> this gives the next_hop on whose pending queue you should
848    add the message. */
849 }
850
851
852 /**
853  * Construct a PeerNotifyNewSuccessor message and send it to friend.
854  */
855 void GDS_NEIGHBOURS_handle_notify_new_successor()
856 {
857   
858 }
859
860
861 /**FIXME: Old implementation just to remove error
862  * TODO: Modify this function to handle our get request. 
863  * Perform a GET operation.  Forwards the given request to other
864  * peers.  Does not lookup the key locally.  May do nothing if this is
865  * the only peer in the network (or if we are the closest peer in the
866  * network).
867  *
868  * @param type type of the block
869  * @param options routing options
870  * @param desired_replication_level desired replication count
871  * @param hop_count how many hops did this request traverse so far?
872  * @param key key for the content
873  * @param xquery extended query
874  * @param xquery_size number of bytes in @a xquery
875  * @param reply_bf bloomfilter to filter duplicates
876  * @param reply_bf_mutator mutator for @a reply_bf
877  * @param peer_bf filter for peers not to select (again)
878  */
879 void
880 GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type,
881                            enum GNUNET_DHT_RouteOption options,
882                            uint32_t desired_replication_level,
883                            uint32_t hop_count, const struct GNUNET_HashCode * key,
884                            const void *xquery, size_t xquery_size,
885                            const struct GNUNET_CONTAINER_BloomFilter *reply_bf,
886                            uint32_t reply_bf_mutator,
887                            struct GNUNET_CONTAINER_BloomFilter *peer_bf)
888 {
889
890   /*
891    1. take the key, get the 64 bit value of the key.
892    2. call find_successor to get the successor of the key.
893    3. successor can be either a friend or finger.
894    4. update the field in get message to reflect if its a friend or finger table
895    5. add the put message to pending message and send it. 
896    */
897 }
898
899 /**FIXME: Old implementation just to remove error.
900  * TODO: Modify this function to handle our put request. 
901  * Perform a PUT operation.   Forwards the given request to other
902  * peers.   Does not store the data locally.  Does not give the
903  * data to local clients.  May do nothing if this is the only
904  * peer in the network (or if we are the closest peer in the
905  * network).
906  *
907  * @param type type of the block
908  * @param options routing options
909  * @param desired_replication_level desired replication count
910  * @param expiration_time when does the content expire
911  * @param hop_count how many hops has this message traversed so far
912  * @param bf Bloom filter of peers this PUT has already traversed
913  * @param key key for the content
914  * @param put_path_length number of entries in @a put_path
915  * @param put_path peers this request has traversed so far (if tracked)
916  * @param data payload to store
917  * @param data_size number of bytes in @a data
918  */
919 void
920 GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
921                            enum GNUNET_DHT_RouteOption options,
922                            uint32_t desired_replication_level,
923                            struct GNUNET_TIME_Absolute expiration_time,
924                            uint32_t hop_count,
925                            struct GNUNET_CONTAINER_BloomFilter *bf,
926                            const struct GNUNET_HashCode *key,
927                            unsigned int put_path_length,
928                            struct GNUNET_PeerIdentity *put_path,
929                            const void *data, size_t data_size)
930 {
931
932    /*
933    1. take the key, get the 64 bit value of the key.
934    2. call find_successor to get the successor of the key.
935    3. successor can be either a friend or finger.
936    4. update the field in put message to reflect if its a friend or finger table
937    5. add the put message to pending message and send it. 
938    */
939 }
940
941
942 /**
943  * FIXME: Check if this function actually iterates or not. 
944  * Randomly choose one of your friends from the friends_peer map
945  * @return Friend
946  */
947 static struct FriendInfo *
948 select_random_friend()
949 {  
950   unsigned int current_size;
951   unsigned int *index; 
952   unsigned int j = 0;
953   struct GNUNET_CONTAINER_MultiPeerMapIterator *iter;
954   struct GNUNET_PeerIdentity key_ret;
955   struct FriendInfo *friend;
956   
957   current_size = GNUNET_CONTAINER_multipeermap_size(friend_peermap);
958   
959   /* Element stored at this index in friend_peermap should be selected friend. */
960   index = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_WEAK, current_size);
961   
962   /* Create an iterator for friend_peermap. */
963   iter = GNUNET_CONTAINER_multipeermap_iterator_create(friend_peermap);
964   
965   /* Set the position of iterator to index. */
966   while(j < (*index))
967   {
968     if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next(iter,NULL,NULL))
969     {
970       /* FIXME: I don't think we are actually incrementing iter. iter is always
971        pointing to the same element. */
972       j++;
973     }
974     else 
975       return NULL;
976   }  
977   
978   if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next(iter,&key_ret,(const void **)&friend))
979   {
980     return friend;
981   }
982
983   return NULL;
984 }
985
986
987 /**
988  * Compute finger_identity to which we want to setup the trail
989  * FIXME: If we maintain a index that is value of current_finger_index
990  * to which a particular entry in finger map corresponds then should we first
991  * check if there is already an entry for that index. If yes then don't
992  * search for trail to that finger. 
993  * @return finger_identity 
994  */
995 static uint64_t *
996 compute_finger_identity()
997 {
998   uint64_t *my_id64 ;
999   uint64_t *finger_identity64;
1000   
1001   my_id64 = GNUNET_malloc (sizeof (uint64_t));
1002   finger_identity64 = GNUNET_malloc (sizeof (uint64_t));
1003   
1004   memcpy(my_id64, &(my_identity.public_key.q_y), sizeof (uint64_t));
1005   *finger_identity64 = fmod ((*my_id64 + pow (2,current_finger_index)),( (pow (2,MAX_FINGERS))));
1006   
1007   return finger_identity64;
1008 }
1009
1010
1011 /**
1012  * TODO: Implement after testing friend/finger map.
1013  * TODO: Handle the case when we already have a trail to our predecessor in
1014  * the network. 
1015  * This function will be needed when we are handling node joins/fails
1016  * to maintain correct pointer to our predecessor and successor in the network. 
1017  * Find immediate predecessor in the network.
1018  * @param me my own identity
1019  * @return peer identity of immediate predecessor.
1020  */
1021 static uint64_t *
1022 find_immediate_predecessor()
1023 {
1024   /* Using your own peer identity, calculate your predecessor
1025    * in the network. Try to setup path to this predecessor using
1026    * the same logic as used for other fingers. 
1027    * If we already have a trail to our predecessor then send NULL and 
1028    * calling function should be able to handle that case.
1029   */
1030   /* FIXME: O could be a valid peer id, return something else. */
1031   return 0;
1032 }
1033
1034
1035 /**
1036  * Periodically verify your own immediate successor and 
1037  * tell your successor about yourself. 
1038  * 
1039  * @param cls closure for this task
1040  * @param tc the context under which the task is running
1041  */
1042 static void
1043 send_verify_successor_message(void *cls,
1044           const struct GNUNET_SCHEDULER_TaskContext *tc )
1045 {
1046   /* 
1047    * FIXME:
1048    * Should we have a new message type
1049    * 1. like who is your predecessor.
1050    * 2. notify
1051    In this function
1052    1. ask your immediate successor ( its stored in your finger table with 
1053    field that notes that its immediate successor) who is its predecessor.
1054    2. Then after getting the reply, check if its you.
1055    3. If not then update the new successor and your successor
1056    and notify the new successor that you are its new predecessor.
1057    */
1058   
1059   /* okay so you first need to construct a messsage that you want to send 
1060    to your "successor". but here you should just call another function which 
1061    will construct the message and send it to first friend in the trial to 
1062    reach our successor. */
1063   struct GNUNET_TIME_Relative next_send_time;
1064   //struct GNUNET_PeerIdentity *successor;
1065   //struct FingerInfo *finger;
1066   
1067   /* Iterate over your finger peermap to find the element with successor field set.
1068    That field is your successor. */
1069   
1070   /* In this function you should send your successor id, trail to reach that successor,
1071    trail_length, current_trial_index. */
1072   GDS_NEIGUBOURS_handle_verify_successor();
1073   
1074   /* FIXME: Use a random value so that this message is send not at the same
1075    interval as send_find_finger_trail_message. */
1076   next_send_time.rel_value_us =
1077       DHT_MINIMUM_FIND_FINGER_TRAIL_INTERVAL.rel_value_us +
1078       GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
1079                                 DHT_MAXIMUM_FIND_FINGER_TRAIL_INTERVAL.rel_value_us /
1080                                 (current_finger_index + 1));
1081  
1082   verify_successor =
1083       GNUNET_SCHEDULER_add_delayed (next_send_time, &send_verify_successor_message,
1084                                     NULL);
1085 }
1086
1087
1088 /**
1089  * Task to send a find finger trail message. We attempt to find trail
1090  * to our finger and successor in the network.
1091  *
1092  * @param cls closure for this task
1093  * @param tc the context under which the task is running
1094  */
1095 static void
1096 send_find_finger_trail_message (void *cls,
1097                         const struct GNUNET_SCHEDULER_TaskContext *tc)
1098 {
1099   struct FriendInfo *friend;
1100   struct GNUNET_TIME_Relative next_send_time;
1101   uint64_t *finger_identity; /* FIXME: Better variable name */ 
1102   struct GNUNET_PeerIdentity *peer_list;
1103   unsigned int successor_flag; /* set to 1 if we are looking for first finger/
1104   our succcessor, else 0. */
1105
1106   /* We already have found trail to each of our possible fingers in the network. */
1107   if (GNUNET_CONTAINER_multipeermap_size (finger_peermap) == MAX_FINGERS)
1108   {
1109     /* FIXME: I call find_immediate_predecessor when I have found trail to 
1110      * all the possible fingers in the network. But we need to find immediate
1111      * predecessor when there is a node failure/join. It may happen before.
1112      * Think of a better strategy to decide when to call this function. 
1113      * We can find trail to our immediate predecessor in the network.
1114      * I think its better to call this after we have trail to our successor set up.
1115      */  
1116     finger_identity = find_immediate_predecessor();  
1117     
1118     if(NULL == finger_identity)
1119     {
1120       /* We already have a trail to reach to immediate predecessor. */
1121       goto new_find_finger_trail_request;
1122     }
1123   }
1124   else
1125   {
1126     finger_identity = compute_finger_identity();
1127     
1128     if(finger_identity == NULL)
1129     {
1130       goto new_find_finger_trail_request;
1131     }
1132   }
1133   
1134   if(0 == current_finger_index)
1135   {
1136     /* We are searching for our successor in the network. */
1137     successor_flag = 1;
1138   }
1139   friend = GNUNET_malloc (sizeof (struct FriendInfo));
1140   friend = select_random_friend();
1141  
1142   /* We found a friend.*/
1143   if(NULL != friend)
1144   { 
1145     unsigned int trail_length = 2;
1146     peer_list = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * trail_length);
1147     memcpy(&peer_list[0], &(my_identity), sizeof (struct GNUNET_PeerIdentity)); 
1148     memcpy(&peer_list[1], &(friend->id), sizeof (struct GNUNET_PeerIdentity)); 
1149     GDS_NEIGHBOURS_handle_trail_setup(&my_identity, finger_identity, 
1150                                       friend, trail_length, peer_list,successor_flag);
1151   }
1152   
1153   /* FIXME: Should we be using current_finger_index to generate random interval.*/
1154   new_find_finger_trail_request:
1155   next_send_time.rel_value_us =
1156       DHT_MINIMUM_FIND_FINGER_TRAIL_INTERVAL.rel_value_us +
1157       GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
1158                                 DHT_MAXIMUM_FIND_FINGER_TRAIL_INTERVAL.rel_value_us /
1159                                 (current_finger_index + 1));
1160  
1161   find_finger_trail_task =
1162       GNUNET_SCHEDULER_add_delayed (next_send_time, &send_find_finger_trail_message,
1163                                     NULL);
1164 }
1165
1166
1167 /**
1168  * Method called whenever a peer connects.
1169  *
1170  * @param cls closure
1171  * @param peer peer identity this notification is about
1172  */
1173 static void
1174 handle_core_connect (void *cls, const struct GNUNET_PeerIdentity *peer)
1175 {
1176   struct FriendInfo *ret;
1177   
1178   /* Check for connect to self message */
1179   if (0 == memcmp (&my_identity, peer, sizeof (struct GNUNET_PeerIdentity)))
1180     return;
1181   
1182   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1183               "Connected to %s\n",
1184               GNUNET_i2s (peer));
1185   
1186   /* If peer already exists in our friend_peermap, then exit. */
1187   if (GNUNET_YES ==
1188       GNUNET_CONTAINER_multipeermap_contains (friend_peermap,
1189                                               peer))
1190   {
1191     GNUNET_break (0);
1192     return;
1193   }
1194
1195   GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# peers connected"), 1,
1196                             GNUNET_NO);
1197
1198   
1199   ret = GNUNET_new (struct FriendInfo);
1200   ret->id = *peer;
1201   
1202   GNUNET_assert (GNUNET_OK ==
1203                  GNUNET_CONTAINER_multipeermap_put (friend_peermap,
1204                                                     peer, ret,
1205                                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1206
1207   
1208   /* got a first connection, good time to start with FIND FINGER TRAIL requests... */
1209   if (1 == GNUNET_CONTAINER_multipeermap_size (friend_peermap))
1210     find_finger_trail_task = GNUNET_SCHEDULER_add_now (&send_find_finger_trail_message, NULL);
1211 }
1212
1213
1214 /**
1215  * FIXME: Implement after testing finger/friend table setup.
1216  * Method called whenever a peer disconnects.
1217  *
1218  * @param cls closure
1219  * @param peer peer identity this notification is about
1220  */
1221 static void
1222 handle_core_disconnect (void *cls,
1223                         const struct GNUNET_PeerIdentity *peer)
1224 {
1225   /**
1226    * 1. remove the friend from the friend map.
1227    * 2. remove the trail for the fingers for which this peer was the first hop.
1228    * 3. start send_find_finger_trail for these fingers to find a new trail 
1229    * in the network.
1230    * 4. Also when a node gets disconnected, how should we update pointers of its
1231    * immediate successor and predecessor in the network ?
1232    * 5. Also how do we distribute the keys in the network?
1233    * 6. Here is case where we started put operation but a peer got disconnected and 
1234       we removed the entry from the table. How to handle such a case. 
1235    */
1236 }
1237
1238
1239 /**
1240  * To be called on core init/fail.
1241  *
1242  * @param cls service closure
1243  * @param identity the public identity of this peer
1244  */
1245 static void
1246 core_init (void *cls,
1247            const struct GNUNET_PeerIdentity *identity)
1248 {
1249   my_identity = *identity;
1250   GNUNET_CRYPTO_hash (identity,
1251                       sizeof (struct GNUNET_PeerIdentity),
1252                       &my_identity_hash);
1253
1254 }
1255
1256
1257 /**
1258  * Core handler for p2p put requests.
1259  *
1260  * @param cls closure
1261  * @param peer sender of the request
1262  * @param message message
1263  * @param peer peer identity this notification is about
1264  * @return #GNUNET_OK to keep the connection open,
1265  *         #GNUNET_SYSERR to close it (signal serious error)
1266  */
1267 static int
1268 handle_dht_p2p_put (void *cls,
1269                     const struct GNUNET_PeerIdentity *peer,
1270                     const struct GNUNET_MessageHeader *message)
1271 {
1272     /**
1273     1. Check if destination is friend or finger.
1274     2. If finger then get the next hop from routing table and 
1275      * call GDS_NEGIHBOURS_handle_get.
1276     3. If friend then call find_successor to get the next hop and again
1277      * call GDS_NEIGHBOURS_handle_get to send to chosen hop.
1278      4. If you are the destination then do datacache_store.
1279      */
1280   return 0;
1281 }
1282
1283
1284 /**
1285  * Core handler for p2p get requests.
1286  *
1287  * @param cls closure
1288  * @param peer sender of the request
1289  * @param message message
1290  * @return #GNUNET_OK to keep the connection open,
1291  *         #GNUNET_SYSERR to close it (signal serious error)
1292  */
1293 static int
1294 handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer,
1295                     const struct GNUNET_MessageHeader *message)
1296 {
1297   /**
1298     1. Check if destination is friend or finger.
1299     2. If finger then get the next hop from routing table and 
1300      * call GDS_NEGIHBOURS_handle_get.
1301     3. If friend then call find_successor to get the next hop and again
1302      * call GDS_NEIGHBOURS_handle_get to send to chosen hop.
1303      4. If you are the destination then send the data back to source peer
1304    * Assuming we have trail setup we can
1305    * either store the whole trail or again do the search process..
1306      */
1307   return 0;
1308 }
1309
1310 /**
1311  * Compare two peer identities.  Used with qsort or bsearch.
1312  *
1313  * @param p1 Some peer identity.
1314  * @param p2 Some peer identity.
1315  * @return 1 if p1 > p2, -1 if p1 < p2 and 0 if p1 == p2.
1316  */
1317 static int
1318 peer_id_cmp (const void *p1, const void *p2)
1319 {
1320   return memcmp (p1, p2, sizeof (uint64_t));
1321 }
1322
1323 /**
1324  * Returns the previous element of value in all_known_peers.
1325  * @param all_known_peers list of all the peers
1326  * @param value value we have to search in the all_known_peers.
1327  * @return 
1328  */
1329 static struct GNUNET_PeerIdentity *
1330 binary_search(struct GNUNET_PeerIdentity *all_known_peers, uint64_t *value,
1331               unsigned int size)
1332 {
1333   unsigned int first;
1334   unsigned int last;
1335   unsigned int middle;
1336   struct GNUNET_PeerIdentity *successor;
1337   successor = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
1338   
1339   first = 0;
1340   last = size - 1;
1341   middle = (first + last)/2;
1342   
1343   while(first <= last)
1344   {
1345     /* all_known_peers[middle] > value*/
1346     if(0 > peer_id_cmp(&all_known_peers[middle], &value))
1347     {
1348       first = middle + 1; 
1349     }
1350     else if(0 == peer_id_cmp(&all_known_peers[middle], &value))
1351     {
1352       if(middle == 0)
1353       {
1354         successor = &(all_known_peers[size - 1]);
1355       }
1356       else
1357         successor = &(all_known_peers[middle-1]);
1358     }
1359     else
1360     {
1361        last = middle - 1;
1362     }
1363   
1364     middle = (first + last)/2;  
1365   }
1366   return successor;
1367 }
1368
1369
1370
1371 /**
1372  * Find closest successor for the value.
1373  * @param value Value for which we are looking for successor
1374  * @param current_destination NULL if my_identity is successor else finger/friend 
1375  * identity 
1376  * @param type Next destination type
1377  * @return Peer identity of next destination i.e. successor of value. 
1378  */
1379 static struct GNUNET_PeerIdentity *
1380 find_successor(uint64_t *value, struct GNUNET_PeerIdentity *current_destination,
1381                enum current_destination_type *type)
1382 {
1383   /* 1. Create an array and copy all the peer identites from finger_peermap, 
1384    friend_peermap, your own identity and value you are searching. 
1385    2. Sort the array. 
1386    3. Do a binary search on array to find the location of your value. 
1387    4. previous element of the value is your successor. 
1388    5. search for the successor in friend/finger/my_identity .
1389    6. if my_identity, then return NULL and set type to my_identity 
1390    7. if friend, then return friend->id and set type to friend.
1391    8. if finger, then set current_destination = finger and return the first
1392    element from the trail list of finger as next_hop. */
1393   struct GNUNET_CONTAINER_MultiPeerMapIterator *friend_iter;
1394   struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
1395   struct GNUNET_PeerIdentity key_ret;
1396   struct FriendInfo *friend;
1397   struct FingerInfo *finger;
1398   unsigned int finger_index;
1399   unsigned int friend_index;
1400   struct GNUNET_PeerIdentity *all_known_peers;
1401   struct GNUNET_PeerIdentity *successor;
1402   unsigned int size;
1403   unsigned int j;
1404   /* SUPU: 2 is added for my_identity and value. */
1405   size = GNUNET_CONTAINER_multipeermap_size (friend_peermap)+
1406          GNUNET_CONTAINER_multipeermap_size (finger_peermap)+
1407          2;
1408   
1409   all_known_peers = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * size);
1410   
1411   j = 0;
1412   memcpy(&all_known_peers[j], &(my_identity), sizeof (struct GNUNET_PeerIdentity));
1413   j++;
1414   memcpy(&all_known_peers[j], value, sizeof(struct GNUNET_PeerIdentity));
1415   
1416   /* Iterate over friend peermap and copy all the elements into array. */
1417   friend_iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap); 
1418   for (friend_index = 0; friend_index < GNUNET_CONTAINER_multipeermap_size (friend_peermap); friend_index++)
1419   {
1420     /* FIXME: I don't think we are actually iterating.
1421      Read about how to iterate over the multipeermap. */
1422     if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next(friend_iter,&key_ret,(const void **)&friend)) 
1423     {
1424       memcpy(&all_known_peers[j], &(friend->id), sizeof (struct GNUNET_PeerIdentity));
1425       j++;
1426     }
1427   }
1428   
1429   /* Iterate over finger map and copy all the entries into all_known_peers array. */
1430   finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);  
1431   for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++)
1432   {
1433     /* FIXME: I don't think we are actually iterating.
1434      Read about how to iterate over the multi peer map. */
1435     if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next(finger_iter,&key_ret,(const void **)&finger)) 
1436     {
1437       memcpy(&all_known_peers[j], &(finger->finger_identity), sizeof (struct GNUNET_PeerIdentity));
1438       j++;
1439     }
1440   }
1441   
1442   qsort(all_known_peers, size, sizeof (struct GNUNET_PeerIdentity), &peer_id_cmp);
1443   
1444   /* search value in all_known_peers array. */
1445   successor = binary_search(all_known_peers, value, size);
1446   
1447   /* compare successor with my_identity, finger and friend */
1448   if(0 == GNUNET_CRYPTO_cmp_peer_identity(&(my_identity), successor))
1449   {
1450     *type = MY_ID;
1451     return NULL;
1452   }
1453   else if (GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains (friend_peermap,
1454                                               successor))
1455   {
1456     *type = FRIEND;
1457     memcpy(current_destination, successor, sizeof (struct GNUNET_PeerIdentity));
1458     return successor;
1459   }
1460   else if (GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains (finger_peermap,
1461                                               successor))
1462   {
1463     *type = FINGER;
1464     memcpy(current_destination, successor, sizeof (struct GNUNET_PeerIdentity));
1465     /* get the corresponding finger for succcesor and read the first element from
1466      the trail list and return that element. */
1467     struct FingerInfo *successor_finger;
1468     struct GNUNET_PeerIdentity *next_hop;
1469     next_hop = GNUNET_malloc(sizeof (struct GNUNET_PeerIdentity));
1470     successor_finger = GNUNET_malloc (sizeof (struct FingerInfo));
1471     successor_finger = GNUNET_CONTAINER_multipeermap_get (finger_peermap, successor);
1472     memcpy(next_hop, &(successor_finger->trail_peer_list[0]), sizeof (struct GNUNET_PeerIdentity));
1473     return next_hop;
1474   }
1475   return NULL;
1476 }
1477
1478
1479 /**
1480  * Handle a PeerTrailSetupMessage. 
1481  * @param cls closure
1482  * @param message message
1483  * @param peer peer identity this notification is about
1484  * @return GNUNET_OK on success, GNUNET_SYSERR on error
1485  */
1486 static int
1487 handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer,
1488                     const struct GNUNET_MessageHeader *message)
1489 {
1490   struct PeerTrailSetupMessage *trail_setup; 
1491   struct GNUNET_PeerIdentity *next_hop; 
1492   struct FriendInfo *target_friend;
1493   size_t msize;
1494   uint32_t trail_length;
1495   enum current_destination_type peer_type;
1496   struct GNUNET_PeerIdentity *trail_peer_list; 
1497   uint32_t current_trail_index;
1498   struct GNUNET_PeerIdentity *next_peer;
1499
1500   
1501   /* parse and validate message. */
1502   msize = ntohs (message->size);
1503   if (msize < sizeof (struct PeerTrailSetupMessage))
1504   {
1505     GNUNET_break_op (0);
1506     return GNUNET_YES;
1507   }
1508   
1509   trail_setup = (struct PeerTrailSetupMessage *) message; 
1510   trail_length = ntohl (trail_setup->trail_length); 
1511   peer_type = ntohl (trail_setup->current_destination_type);
1512   trail_peer_list = (struct GNUNET_PeerIdentity *) &trail_setup[1];
1513   
1514   if ((msize <
1515        sizeof (struct PeerTrailSetupMessage) +
1516        trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
1517       (trail_length >
1518        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
1519   {
1520     GNUNET_break_op (0);
1521     return GNUNET_YES; /*TODO: Why do we send GNUNET_YES here? */
1522   }
1523  
1524   
1525   GNUNET_STATISTICS_update (GDS_stats,
1526                             gettext_noop ("# TRAIL SETUP requests received"), 1,
1527                             GNUNET_NO);
1528   GNUNET_STATISTICS_update (GDS_stats,
1529                             gettext_noop ("# TRAIL SETUP bytes received"), msize,
1530                             GNUNET_NO);
1531   
1532   if(peer_type == FRIEND)
1533   {
1534     if(0 == (GNUNET_CRYPTO_cmp_peer_identity(&(trail_setup->current_destination),&my_identity)))
1535     {
1536       next_hop = find_successor(&(trail_setup->destination_finger),&(trail_setup->current_destination),&(peer_type));
1537     }
1538     else
1539       return GNUNET_SYSERR; /*TODO: Should we handle this case differently? */
1540   }
1541   else if(peer_type == FINGER)
1542   {
1543     if(0 != (GNUNET_CRYPTO_cmp_peer_identity(&(trail_setup->current_destination),&my_identity)))
1544     {
1545       /* I am part of trail. 
1546        SUPU: So, I should ask for next hop to reach the current_destination which is the finger
1547        for which this packet has been sent. */
1548       next_hop = GDS_ROUTING_search(&(trail_setup->source_peer),&(trail_setup->current_destination));
1549       
1550       /*TODO: 
1551        call find_successor and compare the two peer ids 
1552        and choose whichever is closest to the destination finger. */
1553     } 
1554     else
1555     {
1556       /* I am the current_destination finger
1557        FIXME: Why are we sending current_destination to find_successor. 
1558        In this case, is it safe to assume current_Destination = my_identity.
1559        I guess we are sending current_destination so that we update it with new
1560        current_destination, if could either me, friend or finger.*/
1561       next_hop = find_successor(&(trail_setup->destination_finger),&(trail_setup->current_destination),&(peer_type));
1562     }
1563   }
1564    
1565   /* If you are the next hop */
1566   if(peer_type == MY_ID)
1567   {
1568     /* FIXME: Verify if its allowed here to definer peer_list and define it
1569        again in the next block below? */
1570       struct GNUNET_PeerIdentity *peer_list;
1571       peer_list = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * (trail_length));
1572       memcpy(peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
1573       current_trail_index = trail_length - 2;
1574       next_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); //FIXME: Do we need to allocate the memory?
1575       memcpy(next_peer, &peer_list[current_trail_index], sizeof (struct GNUNET_PeerIdentity));
1576       
1577       target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_peer);
1578      
1579       /* FIXME: It does not find a friend. Could be possible error in find_successor 
1580        function. Change the logic in find_successor and change it again. */
1581    
1582       /* FIXME: Here as destination_finger is 64 bit instead of struct
1583        GNUNET_PeerIdentity, but you need destination_peer id. If you calling the 
1584        function handle_Trail_setup_result from here, it means you are the
1585        destination. So, you can send your own identity. */
1586       GDS_NEIGHBOURS_handle_trail_setup_result(&(trail_setup->source_peer),
1587                                                &(my_identity),
1588                                                target_friend, trail_length,
1589                                                peer_list,current_trail_index,
1590                                                trail_setup->successor_flag);
1591   
1592     return GNUNET_YES;
1593   }
1594   
1595   /* Add next_hop to list of peers that trail setup message have traversed so far
1596    and increment trail length. */
1597   struct GNUNET_PeerIdentity *peer_list;
1598   peer_list = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * (trail_length + 1));
1599   memcpy(peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
1600   memcpy(&peer_list[trail_length], next_hop, sizeof (struct GNUNET_PeerIdentity));
1601   trail_length++;
1602   
1603   target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
1604   
1605   if(peer_type == FINGER)
1606   {
1607     GDS_ROUTING_add(&(trail_setup->source_peer),&(trail_setup->current_destination),next_hop);
1608   }
1609   
1610   GDS_NEIGHBOURS_handle_trail_setup(&(trail_setup->source_peer),
1611                                     &(trail_setup->destination_finger),
1612                                     target_friend,
1613                                     trail_setup->trail_length,
1614                                     peer_list,trail_setup->successor_flag);
1615 return GNUNET_YES;
1616 }
1617
1618
1619 /**
1620  * FIXME : Add interval field. 
1621  * When adding successor or predeccsor, update a field to
1622  * specify that this entry is not a finger but immediate
1623  * successor or predeccesor. 
1624  * Add an entry in finger table. 
1625  * @param finger Finger to be added to finger table
1626  * @param peer_list peers this request has traversed so far
1627  * @param trail_length Numbers of peers in the trail.
1628  */
1629 static 
1630 void finger_table_add(struct GNUNET_PeerIdentity *finger,
1631                       const struct GNUNET_PeerIdentity *peer_list,
1632                       unsigned int trail_length,
1633                       unsigned int successor_flag)
1634 {
1635   /*FIXME: okay so there are two fields. one we should remember what finger 
1636    identity we were looking for and what successor id we got. */
1637   struct FingerInfo *finger_entry;
1638   finger_entry = GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity));
1639   memcpy(&(finger_entry->finger_identity), finger, sizeof(struct GNUNET_PeerIdentity));
1640   memcpy(&(finger_entry->trail_peer_list), peer_list, sizeof(struct GNUNET_PeerIdentity)
1641                                                       * trail_length);
1642   finger_entry->successor = successor_flag;
1643   if (1 == GNUNET_CONTAINER_multipeermap_size (finger_peermap))
1644     verify_successor = GNUNET_SCHEDULER_add_now (&send_verify_successor_message, NULL);
1645 }
1646
1647
1648 /**
1649  * Core handle for p2p trail construction result messages.
1650  * @param cls closure
1651  * @param message message
1652  * @param peer peer identity this notification is about
1653  * @return GNUNET_OK on success, GNUNET_SYSERR on error
1654  */
1655 static int
1656 handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *peer,
1657                     const struct GNUNET_MessageHeader *message)
1658 {
1659   struct PeerTrailSetupResultMessage *trail_result;
1660   size_t msize;
1661   uint32_t trail_length;
1662   const struct GNUNET_PeerIdentity *trail_peer_list;
1663   uint32_t current_trail_index;
1664   struct GNUNET_PeerIdentity *next_peer;
1665   struct FriendInfo *target_friend;
1666   
1667   msize = ntohs (message->size);
1668   if (msize < sizeof (struct PeerTrailSetupMessage))
1669   {
1670     GNUNET_break_op (0);
1671     return GNUNET_YES;
1672   }
1673   
1674   trail_result = (struct PeerTrailSetupResultMessage *) message; 
1675   trail_length = ntohl (trail_result->trail_length); 
1676   current_trail_index = ntohl(trail_result->current_index);
1677   trail_peer_list = (struct GNUNET_PeerIdentity *) &trail_result[1];
1678   
1679   if ((msize <
1680        sizeof (struct PeerTrailSetupResultMessage) +
1681        trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
1682       (trail_length >
1683        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
1684   {
1685     GNUNET_break_op (0);
1686     return GNUNET_YES;
1687   }
1688  
1689   if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_result->current_destination), &my_identity)))
1690   {
1691     /* Am I the destination? */
1692     if( 0 == (GNUNET_CRYPTO_cmp_peer_identity(&(trail_result->destination_peer), &my_identity)))
1693     {
1694       finger_table_add(&(trail_result->finger), trail_peer_list,trail_length,trail_result->successor_flag);
1695       return GNUNET_YES;
1696     }
1697     else
1698     {
1699       next_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
1700       current_trail_index = current_trail_index - 1;
1701       memcpy(next_peer, &(trail_peer_list[trail_length-1]), sizeof (struct GNUNET_PeerIdentity));
1702       target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_peer);
1703     
1704       GDS_NEIGHBOURS_handle_trail_setup_result(&(trail_result->destination_peer),
1705                                                &(trail_result->finger),
1706                                                target_friend, trail_length,
1707                                                trail_peer_list,current_trail_index,
1708                                                trail_result->successor_flag);
1709       return GNUNET_YES;
1710     }
1711   }
1712   else
1713     return GNUNET_SYSERR;
1714 }
1715
1716
1717 /**
1718  * Core handle for p2p verify successor messages.
1719  * @return GNUNET_OK on success, GNUNET_SYSERR on error
1720  */
1721 static int
1722 handle_dht_p2p_verify_successor()
1723 {
1724   /*
1725    * In this function you have received the message verify successor,
1726    * Now, either you are the destination or just part of the trail.
1727    * As we already know the whole path find out the next destination
1728    * and pass the packet forward.
1729    * If you are the final destination, check who is your predecessor.  
1730    * and send your predecessor back to calling function. 
1731    * FIXME: Should we have a different handler function for it. 
1732    */
1733   return GNUNET_YES;
1734 }
1735
1736 /**
1737  * Core handle for p2p notify successor messages.
1738  * @return GNUNET_OK on success, GNUNET_SYSERR on error
1739  */
1740 static int
1741 handle_dht_p2p_notify_new_successor()
1742 {
1743   /*
1744    * So, if you are the destination you should update your
1745    * predecessor field with peer id of source peer of this message.
1746    * If you are not the destination peer, then just check your routing
1747    * table and pass on the message. 
1748    */
1749   return GNUNET_YES;
1750 }
1751
1752 /**
1753  * Core handle for p2p verify successor result messages.
1754  * @return GNUNET_OK on success, GNUNET_SYSERR on error
1755  */
1756 static int
1757 handle_dht_p2p_verify_successor_result()
1758 {
1759   /*
1760    * In this function you have received the message verify successor result,
1761    If you are not the destination, just pass this message forward
1762    * if you are destination,
1763    * then check if immediate predecessor of this peer is you or someone else.
1764    * If its you, then don't do anything.
1765    * If its some one else, then call notify method to let your new successor
1766    * know that you are its predecessor. 
1767    */
1768   return GNUNET_YES;
1769 }
1770
1771
1772 /**
1773  * Initialize neighbours subsystem.
1774  * @return GNUNET_OK on success, GNUNET_SYSERR on error
1775  */
1776 int
1777 GDS_NEIGHBOURS_init()
1778 {
1779   static struct GNUNET_CORE_MessageHandler core_handlers[] = {
1780     {&handle_dht_p2p_get, GNUNET_MESSAGE_TYPE_DHT_P2P_GET, 0},
1781     {&handle_dht_p2p_put, GNUNET_MESSAGE_TYPE_DHT_P2P_PUT, 0},
1782     {&handle_dht_p2p_trail_setup, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP, 0},
1783     {&handle_dht_p2p_trail_setup_result, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP_RESULT, 0},
1784     {&handle_dht_p2p_verify_successor, GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR, 0},
1785     {&handle_dht_p2p_notify_new_successor, GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_NEW_SUCCESSOR, 0},
1786     {&handle_dht_p2p_verify_successor_result, GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR_RESULT, 0},
1787     {NULL, 0, 0}
1788   };
1789
1790   /*TODO: What is ATS? Why do we need it? */
1791   atsAPI = GNUNET_ATS_performance_init (GDS_cfg, NULL, NULL);
1792   core_api =
1793     GNUNET_CORE_connect (GDS_cfg, NULL, &core_init, &handle_core_connect,
1794                            &handle_core_disconnect, NULL, GNUNET_NO, NULL,
1795                            GNUNET_NO, core_handlers);
1796   if (core_api == NULL)
1797     return GNUNET_SYSERR;
1798
1799   friend_peermap = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_NO);
1800   finger_peermap = GNUNET_CONTAINER_multipeermap_create (MAX_FINGERS, GNUNET_NO); 
1801  
1802   return GNUNET_OK;
1803 }
1804
1805
1806 /**
1807  * Shutdown neighbours subsystem.
1808  */
1809 void
1810 GDS_NEIGHBOURS_done ()
1811 {
1812   if (NULL == core_api)
1813     return;
1814   
1815   GNUNET_CORE_disconnect (core_api);
1816   core_api = NULL;
1817   GNUNET_ATS_performance_done (atsAPI);
1818   atsAPI = NULL;
1819
1820   /* FIXME: Once handle_core_disconnect is implemented, both below assertion should not
1821    fail. */
1822   GNUNET_assert (0 == GNUNET_CONTAINER_multipeermap_size (friend_peermap));
1823   GNUNET_CONTAINER_multipeermap_destroy (friend_peermap);
1824   friend_peermap = NULL;
1825
1826   GNUNET_assert (0 == GNUNET_CONTAINER_multipeermap_size (finger_peermap));
1827   GNUNET_CONTAINER_multipeermap_destroy (finger_peermap);
1828   finger_peermap = NULL;
1829
1830   if (GNUNET_SCHEDULER_NO_TASK != find_finger_trail_task)
1831   {
1832     GNUNET_SCHEDULER_cancel (find_finger_trail_task);
1833     find_finger_trail_task = GNUNET_SCHEDULER_NO_TASK;
1834   }
1835   
1836   /* FIXME: fix_fingers will also be a task like this.
1837      Add it later. */
1838   if (GNUNET_SCHEDULER_NO_TASK != verify_successor)
1839   {
1840     GNUNET_SCHEDULER_cancel (verify_successor);
1841     verify_successor = GNUNET_SCHEDULER_NO_TASK;
1842   }
1843   
1844 }
1845
1846
1847 /**
1848  * Get the ID of the local node.
1849  *
1850  * @return identity of the local node
1851  */
1852 struct GNUNET_PeerIdentity *
1853 GDS_NEIGHBOURS_get_id ()
1854 {
1855   return &my_identity;
1856 }
1857
1858
1859 /* end of gnunet-service-xdht_neighbours.c */