fix #3275 with solution from https://gnunet.org/bugs/view.php?id=3275#c8029
[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 bucket and neighbour 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 /* The maximum possible fingers of a peer. */
52 #define MAX_FINGERS 256
53
54 /**
55  * Maximum allowed number of pending messages per peer.
56  */
57 #define MAXIMUM_PENDING_PER_PEER 64
58
59 /**
60  * How long at least to wait before sending another find finger trail request.
61  */
62 #define DHT_MINIMUM_FIND_PEER_INTERVAL GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 30)
63
64 /**
65  * How long at most to wait before sending another find finger trail request.
66  */
67 #define DHT_MAXIMUM_FIND_PEER_INTERVAL GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 10)
68
69
70 GNUNET_NETWORK_STRUCT_BEGIN
71
72 /* FIXME:
73  * 1) Bloomfilter is not required for X-Vine.
74  * Keep the field now but remove it when implementing PUT/GET.
75  * 2) also, check the field of put/get/result if all are required for
76  * x-vine or not. */
77
78 /**
79  * P2P PUT message
80  */
81 struct PeerPutMessage
82 {
83   /**
84    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_PUT
85    */
86   struct GNUNET_MessageHeader header;
87
88   /**
89    * Processing options
90    */
91   uint32_t options GNUNET_PACKED;
92
93   /**
94    * Content type.
95    */
96   uint32_t type GNUNET_PACKED;
97
98   /**
99    * Hop count
100    */
101   uint32_t hop_count GNUNET_PACKED;
102
103   /**
104    * Replication level for this message
105    */
106   uint32_t desired_replication_level GNUNET_PACKED;
107
108   /**
109    * Length of the PUT path that follows (if tracked).
110    */
111   uint32_t put_path_length GNUNET_PACKED;
112
113   /**
114    * When does the content expire?
115    */
116   struct GNUNET_TIME_AbsoluteNBO expiration_time;
117
118   /**
119    * Bloomfilter (for peer identities) to stop circular routes
120    */
121   char bloomfilter[DHT_BLOOM_SIZE];
122
123   /**
124    * The key we are storing under.
125    */
126   struct GNUNET_HashCode key;
127
128   /* put path (if tracked) */
129
130   /* Payload */
131
132 };
133
134
135 /**
136  * P2P Result message
137  */
138 struct PeerResultMessage
139 {
140   /**
141    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT
142    */
143   struct GNUNET_MessageHeader header;
144
145   /**
146    * Content type.
147    */
148   uint32_t type GNUNET_PACKED;
149
150   /**
151    * Length of the PUT path that follows (if tracked).
152    */
153   uint32_t put_path_length GNUNET_PACKED;
154
155   /**
156    * Length of the GET path that follows (if tracked).
157    */
158   uint32_t get_path_length GNUNET_PACKED;
159
160   /**
161    * When does the content expire?
162    */
163   struct GNUNET_TIME_AbsoluteNBO expiration_time;
164
165   /**
166    * The key of the corresponding GET request.
167    */
168   struct GNUNET_HashCode key;
169
170   /* put path (if tracked) */
171
172   /* get path (if tracked) */
173
174   /* Payload */
175
176 };
177
178
179 /**
180  * P2P GET message
181  */
182 struct PeerGetMessage
183 {
184   /**
185    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_GET
186    */
187   struct GNUNET_MessageHeader header;
188
189   /**
190    * Processing options
191    */
192   uint32_t options GNUNET_PACKED;
193
194   /**
195    * Desired content type.
196    */
197   uint32_t type GNUNET_PACKED;
198
199   /**
200    * Hop count
201    */
202   uint32_t hop_count GNUNET_PACKED;
203
204   /**
205    * Desired replication level for this request.
206    */
207   uint32_t desired_replication_level GNUNET_PACKED;
208
209   /**
210    * Size of the extended query.
211    */
212   uint32_t xquery_size;
213
214   /**
215    * Bloomfilter mutator.
216    */
217   uint32_t bf_mutator;
218
219   /**
220    * Bloomfilter (for peer identities) to stop circular routes
221    */
222   char bloomfilter[DHT_BLOOM_SIZE];
223
224   /**
225    * The key we are looking for.
226    */
227   struct GNUNET_HashCode key;
228
229 };
230
231
232 /**
233  * FIXME : should change the fields
234  * P2P Trail setup message
235  */
236 struct PeerTrailSetupMessage
237 {
238   /**
239    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP
240    */
241   struct GNUNET_MessageHeader header;
242
243   /* Source peer which wants to find trail to one of its finger. */
244   struct GNUNET_PeerIdentity *source_peer;
245
246   /* Finger id to which we want to set up the trail to. */
247   struct GNUNET_PeerIdentity *destination_finger;
248   
249   /* This field contains the peer to which this packet is forwarded. 
250    If temp_destination = my_identity, then check if destination_finger = temp_destination. 
251    If temp_destination != my_identity, then it means you are part of trail that 
252    you take to temp_destination. So, search in routing table. 
253   */
254   struct GNUNET_PeerIdentity *temp_destination;
255   
256   /*FIXME: I want to store a list of all the peer_id which are part of trail in
257    this message
258    Also, when sending the reply back we are just going to read this list
259    backwards. Assuming that we add a new peer at the end of our list. */
260    
261   
262
263 };
264 /**
265  * P2P Trail setup Result message
266  * TODO: Check the fields and if they are really required. 
267  * FIXME: should change the fields
268  * it can contain the peertrailsetup only
269  * and we just read the list backwards and make the
270  * packet reach to destination
271  *There can be lots and lots of cases where the packet are lost but 
272  * as we have non blocking function call we are ok
273  * i think i will implement and verify by printing the design.
274  */
275 struct PeerTrailSetupResultMessage
276 {
277   /**
278    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_RESULT_SETUP
279    */
280   struct GNUNET_MessageHeader header;
281
282   /**
283    * Content type.
284    */
285   uint32_t type GNUNET_PACKED;
286
287   /**
288    * Length of the PUT path that follows (if tracked).
289    */
290   uint32_t put_path_length GNUNET_PACKED;
291
292   /**
293    * Length of the GET path that follows (if tracked).
294    */
295   uint32_t get_path_length GNUNET_PACKED;
296
297   /**
298    * When does the content expire?
299    */
300   struct GNUNET_TIME_AbsoluteNBO expiration_time;
301
302   /**
303    * The key of the corresponding GET request.
304    */
305   struct GNUNET_HashCode key;
306
307   /* put path (if tracked) */
308
309   /* get path (if tracked) */
310
311   /* Payload */
312
313 };
314
315 GNUNET_NETWORK_STRUCT_END
316         
317         
318 /**
319  * Linked list of messages to send to a particular other peer.
320  */
321 struct P2PPendingMessage
322 {
323   /**
324    * Pointer to next item in the list
325    */
326   struct P2PPendingMessage *next;
327
328   /**
329    * Pointer to previous item in the list
330    */
331   struct P2PPendingMessage *prev;
332
333   /**
334    * When does this message time out?
335    */
336   struct GNUNET_TIME_Absolute timeout;
337   
338    /**
339    * Message importance level.  FIXME: used? useful?
340    */
341   unsigned int importance;
342   
343   /**
344    * Actual message to be sent, allocated at the end of the struct:
345    * // msg = (cast) &pm[1];
346    * // memcpy (&pm[1], data, len);
347    */
348   const struct GNUNET_MessageHeader *msg;
349
350 };
351
352
353 /**
354  *  Entry in friend_peers map.
355  */
356 struct FriendInfo
357 {
358   
359   /**
360   * What is the identity of the peer?
361   */
362   struct GNUNET_PeerIdentity id;
363
364  /**
365   * Count of outstanding messages for peer.
366   */
367  unsigned int pending_count;
368
369  /**
370   * Head of pending messages to be sent to this peer.
371   */
372  struct P2PPendingMessage *head;
373
374  /**
375   * Tail of pending messages to be sent to this peer.
376   */
377  struct P2PPendingMessage *tail;
378
379   
380  /**
381   * TODO - How and where to use this?
382   * Core handle for sending messages to this peer.
383   */
384  struct GNUNET_CORE_TransmitHandle *th;
385
386 };
387
388 /**
389  *  Linked List of peers which are part of trail to reach a particular Finger.
390  */
391 struct TrailList
392 {
393    /**
394    * Pointer to next item in the list
395    */
396    struct TrailList *next;
397     
398    /**
399    * Pointer to previous item in the list
400    */
401    struct TrailList *prev;
402 };
403
404 /**
405  * Entry in finger_peers map.
406  */
407 struct FingerInfo
408 {
409   /**
410   * What is the identity of the peer?
411   */
412   struct GNUNET_PeerIdentity id;
413   
414   /* FIXME:: Range of keys for which this finger is responsible */
415   /* Start of the interval of keys for which this finger is responsible. */
416   unsigned int interval_start;
417   
418   /* End of the interval of keys for which this finger is responsible. */
419   unsigned int interval_end;
420   
421   
422   /* FIXME:: A double link list which stores the trail to reach it from given peer .*/
423   
424   /**
425    * Head of trail list. 
426    */
427   struct TrailList *head;
428   
429   /**
430    * Tail of trail list.
431    */
432   struct TrailList *tail;
433 };
434
435
436 /**
437  * Task that sends FIND FINGER TRAIL requests.
438  */
439 static GNUNET_SCHEDULER_TaskIdentifier find_finger_trail_task;
440
441 /**
442  * Identity of this peer.
443  */
444 static struct GNUNET_PeerIdentity my_identity;
445
446 /**
447  * Hash of the identity of this peer.
448  */
449 static struct GNUNET_HashCode my_identity_hash;
450
451 /**
452  * Hash map of all the friends of a peer
453  */
454 static struct GNUNET_CONTAINER_MultiPeerMap *friend_peers;
455
456 /**
457  * Hash map of all the fingers of a peer
458  */
459 static struct GNUNET_CONTAINER_MultiPeerMap *finger_peers;
460
461 /**
462  * Handle to ATS.
463  */
464 static struct GNUNET_ATS_PerformanceHandle *atsAPI;
465
466 /**
467  * Handle to CORE.
468  */
469 static struct GNUNET_CORE_Handle *core_api;
470
471 /**
472  * The highest finger_id that we have found trail to.
473  */
474 static unsigned int finger_id;
475
476
477 /**
478  * Called when core is ready to send a message we asked for
479  * out to the destination. At the moment, I have just copied it from previous
480  * code. 
481  *
482  * @param cls the 'struct PeerInfo' of the target peer
483  * @param size number of bytes available in buf
484  * @param buf where the callee should write the message
485  * @return number of bytes written to buf
486  */
487 static size_t
488 core_transmit_notify (void *cls, size_t size, void *buf)
489 {
490   struct FriendInfo *peer = cls;
491   char *cbuf = buf;
492   struct P2PPendingMessage *pending;
493   size_t off;
494   size_t msize;
495
496   peer->th = NULL;
497   while ((NULL != (pending = peer->head)) &&
498          (0 == GNUNET_TIME_absolute_get_remaining (pending->timeout).rel_value_us))
499   {
500     peer->pending_count--;
501     GNUNET_CONTAINER_DLL_remove (peer->head, peer->tail, pending);
502     GNUNET_free (pending);
503   }
504   if (pending == NULL)
505   {
506     /* no messages pending */
507     return 0;
508   }
509   if (buf == NULL)
510   {
511     peer->th =
512         GNUNET_CORE_notify_transmit_ready (core_api, GNUNET_NO,
513                                            pending->importance,
514                                            GNUNET_TIME_absolute_get_remaining
515                                            (pending->timeout), &peer->id,
516                                            ntohs (pending->msg->size),
517                                            &core_transmit_notify, peer);
518     GNUNET_break (NULL != peer->th);
519     return 0;
520   }
521   off = 0;
522   while ((NULL != (pending = peer->head)) &&
523          (size - off >= (msize = ntohs (pending->msg->size))))
524   {
525     GNUNET_STATISTICS_update (GDS_stats,
526                               gettext_noop
527                               ("# Bytes transmitted to other peers"), msize,
528                               GNUNET_NO);
529     memcpy (&cbuf[off], pending->msg, msize);
530     off += msize;
531     peer->pending_count--;
532     GNUNET_CONTAINER_DLL_remove (peer->head, peer->tail, pending);
533     GNUNET_free (pending);
534   }
535   if (peer->head != NULL)
536   {
537     peer->th =
538         GNUNET_CORE_notify_transmit_ready (core_api, GNUNET_NO,
539                                            pending->importance,
540                                            GNUNET_TIME_absolute_get_remaining
541                                            (pending->timeout), &peer->id, msize,
542                                            &core_transmit_notify, peer);
543     GNUNET_break (NULL != peer->th);
544   }
545   return off;
546 }
547
548
549 /**
550  * Transmit all messages in the peer's message queue.
551  *
552  * @param peer message queue to process
553  */
554 static void
555 process_peer_queue (struct FriendInfo *peer)
556 {
557   
558   struct P2PPendingMessage *pending;
559
560   if (NULL == (pending = peer->head))
561     return;
562   if (NULL != peer->th)
563     return;
564   GNUNET_STATISTICS_update (GDS_stats,
565                             gettext_noop
566                             ("# Bytes of bandwidth requested from core"),
567                             ntohs (pending->msg->size), GNUNET_NO);
568   /*FIXME : here I don't know the use of importance, time out
569     Will check at run time if its all correct. */
570   peer->th =
571       GNUNET_CORE_notify_transmit_ready (core_api, GNUNET_NO,
572                                          pending->importance,
573                                          GNUNET_TIME_absolute_get_remaining
574                                          (pending->timeout), &peer->id,
575                                          ntohs (pending->msg->size),
576                                          &core_transmit_notify, peer);
577   GNUNET_break (NULL != peer->th);
578 }
579
580
581 /**
582  * This function is similar to get request but used specifically for trail 
583  * construction. I don't know if using GDS_NEIGHBOURS_handle_get is sufficient 
584  * or we need this new function.  
585  * @param Finger id to which we want to setup the trail.
586  * @param Friend id through which we will try to setup the trail. 
587  */
588 void
589 GDS_NEIGHBOURS_trail_setup(struct GNUNET_PeerIdentity *finger_id, 
590                                   struct FriendInfo *target_friend)
591 {
592     /*
593      1. first construct the trail message which should contain
594      * the source peer id, the finger peer id and randomly chosen one of our 
595      * friends peer id. Should there be a new block type?
596      * Construct a message and add it to your peer queue of the friend you have
597      * chosen to send the packet to and then call process_peer_queue.
598      * Just follow GDS_NEIGHBOURS_handle_reply to complete this function. 
599      */
600     /*
601      * FIXME: check if pending message actually contains the correct data.
602      */
603     struct P2PPendingMessage *pending;
604     /* FIXME: why I have defined as **? verify by testing. */
605     struct PeerTrailSetupMessage *tsm;
606    
607       
608     if (target_friend->pending_count >= MAXIMUM_PENDING_PER_PEER)
609     {
610       GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
611                                 1, GNUNET_NO);
612     }
613     
614     pending = GNUNET_malloc (sizeof (struct P2PPendingMessage));
615     tsm = (struct PeerTrailSetupMessage *) &pending[1];
616     pending->msg = &tsm->header;
617     tsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP);
618     tsm->destination_finger = finger_id;
619     tsm->source_peer = &my_identity;
620     GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
621     target_friend->pending_count++;
622     process_peer_queue(target_friend);
623 }
624
625
626 /**FIXME: Old implementation just to remove error
627  * Perform a GET operation.  Forwards the given request to other
628  * peers.  Does not lookup the key locally.  May do nothing if this is
629  * the only peer in the network (or if we are the closest peer in the
630  * network).
631  *
632  * @param type type of the block
633  * @param options routing options
634  * @param desired_replication_level desired replication count
635  * @param hop_count how many hops did this request traverse so far?
636  * @param key key for the content
637  * @param xquery extended query
638  * @param xquery_size number of bytes in @a xquery
639  * @param reply_bf bloomfilter to filter duplicates
640  * @param reply_bf_mutator mutator for @a reply_bf
641  * @param peer_bf filter for peers not to select (again)
642  */
643 void
644 GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type,
645                            enum GNUNET_DHT_RouteOption options,
646                            uint32_t desired_replication_level,
647                            uint32_t hop_count, const struct GNUNET_HashCode * key,
648                            const void *xquery, size_t xquery_size,
649                            const struct GNUNET_CONTAINER_BloomFilter *reply_bf,
650                            uint32_t reply_bf_mutator,
651                            struct GNUNET_CONTAINER_BloomFilter *peer_bf)
652 {
653     
654 }
655
656 /**FIXME: Old implementation just to remove error. 
657  * Perform a PUT operation.   Forwards the given request to other
658  * peers.   Does not store the data locally.  Does not give the
659  * data to local clients.  May do nothing if this is the only
660  * peer in the network (or if we are the closest peer in the
661  * network).
662  *
663  * @param type type of the block
664  * @param options routing options
665  * @param desired_replication_level desired replication count
666  * @param expiration_time when does the content expire
667  * @param hop_count how many hops has this message traversed so far
668  * @param bf Bloom filter of peers this PUT has already traversed
669  * @param key key for the content
670  * @param put_path_length number of entries in @a put_path
671  * @param put_path peers this request has traversed so far (if tracked)
672  * @param data payload to store
673  * @param data_size number of bytes in @a data
674  */
675 void
676 GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
677                            enum GNUNET_DHT_RouteOption options,
678                            uint32_t desired_replication_level,
679                            struct GNUNET_TIME_Absolute expiration_time,
680                            uint32_t hop_count,
681                            struct GNUNET_CONTAINER_BloomFilter *bf,
682                            const struct GNUNET_HashCode *key,
683                            unsigned int put_path_length,
684                            struct GNUNET_PeerIdentity *put_path,
685                            const void *data, size_t data_size)
686 {
687
688 }
689 /**
690  * Randomly choose one of your friends from the friends_peer map
691  * @return Friend
692  */
693 static struct FriendInfo *
694 get_friend()
695 {
696    
697     return NULL;
698 }
699
700 /**
701  * Use Chord formula finger[i]=(n+2^(i-1))mod m,
702  * where i = current finger map index. 
703  * n = own peer identity
704  * m = number of bits in peer id. 
705  * @return finger_peer_id for which we have to find the trail through network. 
706  */
707 static struct GNUNET_PeerIdentity *
708 finger_id_to_search()
709 {
710     /* After finding the finger_id increment the value of 'i'
711      so that the next search begins from there. */
712     struct GNUNET_PeerIdentity *finger_peer_id;
713     
714     
715     
716      /* FIXME: This typecasting is not correct.  */
717     //finger_peer_id = ((unsigned int)(my_identity.public_key.q_y)+(2^(finger_id)))%MAX_FINGERS;
718     
719     /* Increment the next finger_id we should be searching. */
720     finger_id = (finger_id+1)%MAX_FINGERS;
721     
722     return finger_peer_id;
723     
724 }
725
726
727 /**
728  * Task to send a find finger trail message. We attempt to find trail
729  * to our fingers in the network.
730  *
731  * @param cls closure for this task
732  * @param tc the context under which the task is running
733  */
734 static void
735 send_find_finger_trail_message (void *cls,
736                         const struct GNUNET_SCHEDULER_TaskContext *tc)
737 {
738   /* finger we are searching for */
739   struct GNUNET_PeerIdentity *finger_peer_id;
740   struct FriendInfo *friend_peer_id;
741   struct GNUNET_TIME_Relative next_send_time;
742     
743   /* FIXME: Not sure if this is required. Here I am checking if I have
744      already found trail for each of the possible finger. If yes then don't look
745      anymore in the network. */
746   if (GNUNET_CONTAINER_multipeermap_size(finger_peers) == MAX_FINGERS)
747   {
748       return;
749   }
750     
751   /* Find the finger_peer_id to which we want to setup the trial */
752   finger_peer_id = finger_id_to_search();
753    
754   /* Choose a friend randomly from your friend_peers map. */
755   friend_peer_id = get_friend();
756   
757   GDS_NEIGHBOURS_trail_setup(finger_peer_id, friend_peer_id);
758   
759   /* FIXME: Is using finger_id to generate random function ok here. */
760   next_send_time.rel_value_us =
761       DHT_MINIMUM_FIND_PEER_INTERVAL.rel_value_us +
762       GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
763                                 DHT_MAXIMUM_FIND_PEER_INTERVAL.rel_value_us /
764                                 (finger_id + 1));  
765      
766   find_finger_trail_task =
767       GNUNET_SCHEDULER_add_delayed (next_send_time, &send_find_finger_trail_message,
768                                     NULL);
769 }
770
771
772 /**
773  * Method called whenever a peer connects.
774  *
775  * @param cls closure
776  * @param peer peer identity this notification is about
777  */
778 static void
779 handle_core_connect (void *cls, const struct GNUNET_PeerIdentity *peer)
780 {
781  /*When a peer is connected, then add it to your friend_peers map.
782   Also, start an asynchronous method to look for your fingers that you can
783   reach whenever you get the first connection to the peer. Also try to
784   reach to your predecessor. */
785
786   struct FriendInfo *ret;
787   struct GNUNET_HashCode phash;
788
789   /* Check for connect to self message */
790   if (0 == memcmp (&my_identity, peer, sizeof (struct GNUNET_PeerIdentity)))
791     return;
792   
793   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
794               "Connected to %s\n",
795               GNUNET_i2s (peer));
796  
797   if (GNUNET_YES ==
798       GNUNET_CONTAINER_multipeermap_contains (friend_peers,
799                                               peer))
800   {
801     GNUNET_break (0);
802     return;
803   }
804   
805   GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# peers connected"), 1,
806                             GNUNET_NO);
807   GNUNET_CRYPTO_hash (peer,
808                       sizeof (struct GNUNET_PeerIdentity),
809                       &phash);
810
811   ret = GNUNET_new (struct FriendInfo);
812   ret->id = *peer;
813
814   GNUNET_assert (GNUNET_OK ==
815                  GNUNET_CONTAINER_multipeermap_put (friend_peers,
816                                                     peer, ret,
817                                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
818
819   /* got a first connection, good time to start with FIND TRAIL TO FINGER requests... */
820   if (1 == GNUNET_CONTAINER_multipeermap_size(friend_peers))
821    find_finger_trail_task = GNUNET_SCHEDULER_add_now (&send_find_finger_trail_message, NULL);
822 }
823
824
825 /**
826  * Method called whenever a peer disconnects.
827  *
828  * @param cls closure
829  * @param peer peer identity this notification is about
830  */
831 static void
832 handle_core_disconnect (void *cls,
833                         const struct GNUNET_PeerIdentity *peer)
834 {
835
836 }
837
838
839 /**
840  * To be called on core init/fail.
841  *
842  * @param cls service closure
843  * @param identity the public identity of this peer
844  */
845 static void
846 core_init (void *cls,
847            const struct GNUNET_PeerIdentity *identity)
848 {
849   my_identity = *identity;
850   GNUNET_CRYPTO_hash (identity,
851                       sizeof (struct GNUNET_PeerIdentity),
852                       &my_identity_hash);
853 }
854
855
856 /**
857  * Core handler for p2p put requests.
858  *
859  * @param cls closure
860  * @param peer sender of the request
861  * @param message message
862  * @param peer peer identity this notification is about
863  * @return #GNUNET_OK to keep the connection open,
864  *         #GNUNET_SYSERR to close it (signal serious error)
865  */
866 static int
867 handle_dht_p2p_put (void *cls,
868                     const struct GNUNET_PeerIdentity *peer,
869                     const struct GNUNET_MessageHeader *message)
870 {
871     /**
872      1. Search the friend,finger and check your own id to find the closest
873      * predecessor the given key. 
874      2. If self then datache_store
875      3. If friend, then add to peer queue
876      4. If finger, then add to the peer queue of the first hop.Again the
877      * same doubt,how does a peer when it is in handle_dht_p2p_put makes 
878      * a distinction weather it should do a lookup in routing table or finger or
879      * friend table.
880      */
881     return 0;
882 }
883
884
885 /**
886  * Core handler for p2p get requests.
887  *
888  * @param cls closure
889  * @param peer sender of the request
890  * @param message message
891  * @return #GNUNET_OK to keep the connection open,
892  *         #GNUNET_SYSERR to close it (signal serious error)
893  */
894 static int
895 handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer,
896                     const struct GNUNET_MessageHeader *message)
897 {
898     return 0;
899 }
900
901
902 /**
903  * Core handler for p2p result messages.
904  *
905  * @param cls closure
906  * @param message message
907  * @param peer peer identity this notification is about
908  * @return #GNUNET_YES (do not cut p2p connection)
909  */
910 static int
911 handle_dht_p2p_result (void *cls, const struct GNUNET_PeerIdentity *peer,
912                        const struct GNUNET_MessageHeader *message)
913 {
914     return 0;
915 }
916
917
918 /**
919  * Read the trail setup message backwards to find which is the next hop to which
920  * it should be send to. 
921  * @return 
922  */
923 //static
924 struct GNUNET_PeerIdentity *
925 find_next_hop()
926 {
927     return NULL;
928 }
929
930
931 /**
932  * Find the predecessor for given finger_id from the
933  * friend and finger table.
934  * if friend, then just return the friend it
935  * if finger, then return the next hop to forward the packet to.
936  * @return 
937  */
938 //static
939 struct GNUNET_PeerIdentity *
940 find_predecessor()
941 {
942     return NULL;
943 }
944
945
946 /**
947  * Core handler for P2P trail setup message.
948  */
949 static int
950 handle_dht_p2p_trail_setup()
951 {
952     /*
953      * When we get this message from our friend then
954      * 1. Check the destination finger id that the message is looking for. 
955      * 2. If my_identity = destination, then create a trail_setup_result message
956      *    read the path taken to reach to you. read that list backwards to find which 
957      *    friend to forward this trailsetupresult to. find_next_hop()
958      *    call process_peer_queue() to add trailsetupresult message to peer 
959      * 3. If you are not the destination
960      *   then call find_predecessor() to find closest finger to our given finger_id
961      * //GDS_ROUTING_ADD
962      * //GDS_ROUTING_FIND
963      * 
964      */
965    return 0;    
966     
967 }
968
969
970 /**
971  * Core handle for p2p trail construction result messages. 
972  *
973  * @return 
974  */
975 static int
976 handle_dht_p2p_trail_setup_result()
977 {
978     /*
979      Here you got a message that trail is set*/
980     return 0;
981 }
982
983
984 /**
985  * Initialize neighbours subsystem.
986  * @return GNUNET_OK on success, GNUNET_SYSERR on error
987  */
988 int
989 GDS_NEIGHBOURS_init()
990 {
991   static struct GNUNET_CORE_MessageHandler core_handlers[] = {
992     {&handle_dht_p2p_get, GNUNET_MESSAGE_TYPE_DHT_P2P_GET, 0},
993     {&handle_dht_p2p_put, GNUNET_MESSAGE_TYPE_DHT_P2P_PUT, 0},
994     {&handle_dht_p2p_result, GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT, 0},
995     {&handle_dht_p2p_trail_setup, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP, 0},
996     {&handle_dht_p2p_trail_setup_result, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP_RESULT, 0},
997     {NULL, 0, 0}
998   };
999
1000   atsAPI = GNUNET_ATS_performance_init (GDS_cfg, NULL, NULL);
1001   core_api =
1002     GNUNET_CORE_connect (GDS_cfg, NULL, &core_init, &handle_core_connect,
1003                            &handle_core_disconnect, NULL, GNUNET_NO, NULL,
1004                            GNUNET_NO, core_handlers);
1005   if (core_api == NULL)
1006     return GNUNET_SYSERR;
1007
1008   friend_peers = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_NO);
1009   finger_peers = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_NO);
1010   
1011   
1012   return GNUNET_OK;
1013
1014 }
1015
1016
1017 /**
1018  * Shutdown neighbours subsystem.
1019  */
1020 void
1021 GDS_NEIGHBOURS_done ()
1022 {
1023   if (NULL == core_api)
1024     return;
1025   GNUNET_CORE_disconnect (core_api);
1026   core_api = NULL;
1027   GNUNET_ATS_performance_done (atsAPI);
1028   atsAPI = NULL;
1029
1030   GNUNET_assert (0 == GNUNET_CONTAINER_multipeermap_size (friend_peers));
1031   GNUNET_CONTAINER_multipeermap_destroy (friend_peers);
1032   friend_peers = NULL;
1033
1034   GNUNET_assert (0 == GNUNET_CONTAINER_multipeermap_size (finger_peers));
1035   GNUNET_CONTAINER_multipeermap_destroy (finger_peers);
1036   finger_peers = NULL;
1037  
1038   if (GNUNET_SCHEDULER_NO_TASK != find_finger_trail_task)
1039   {
1040     GNUNET_SCHEDULER_cancel (find_finger_trail_task);
1041     find_finger_trail_task = GNUNET_SCHEDULER_NO_TASK;
1042   }
1043 }
1044
1045
1046 /**
1047  * Get the ID of the local node.
1048  *
1049  * @return identity of the local node
1050  */
1051 struct GNUNET_PeerIdentity *
1052 GDS_NEIGHBOURS_get_id ()
1053 {
1054     return &my_identity;
1055 }
1056
1057
1058 /* end of gnunet-service-xdht_neighbours.c */