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