-sending messages / starting random walks
[oweals/gnunet.git] / src / dht / gnunet-service-wdht_neighbours.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2009-2015 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-wdht_neighbours.c
23  * @brief GNUnet DHT service's finger and friend table management code
24  * @author Supriti Singh
25  */
26
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
29 #include "gnunet_block_lib.h"
30 #include "gnunet_hello_lib.h"
31 #include "gnunet_constants.h"
32 #include "gnunet_protocols.h"
33 #include "gnunet_ats_service.h"
34 #include "gnunet_core_service.h"
35 #include "gnunet_datacache_lib.h"
36 #include "gnunet_transport_service.h"
37 #include "gnunet_dht_service.h"
38 #include "gnunet_statistics_service.h"
39 #include "gnunet-service-xdht.h"
40 #include "gnunet-service-wdht_clients.h"
41 #include "gnunet-service-wdht_datacache.h"
42 #include "gnunet-service-wdht_neighbours.h"
43 #include <fenv.h>
44 #include "dht.h"
45
46 #define DEBUG(...)                                           \
47   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
48
49 /**
50  * FIXME
51  */
52 #define FOO_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 2)
53
54 /**
55  * The number of layered ID to use.
56  */
57 #define NUMBER_LAYERED_ID 8
58
59 /**
60  * Contains all the layered ID.
61  */
62 struct GNUNET_PeerIdentity layered_id[NUMBER_LAYERED_ID];
63
64
65 GNUNET_NETWORK_STRUCT_BEGIN
66
67 /**
68  * Setup a finger using the underlay topology ("social network").
69  */
70 struct FingerSetupMessage
71 {
72   /**
73    * Type: #GNUNET_MESSAGE_TYPE_WDHT_FINGER_SETUP
74    */
75   struct GNUNET_MessageHeader header;
76
77   /**
78    * Number of hops this message has taken so far, we stop at
79    * log(NSE), in NBO.
80    */
81   uint16_t hops_taken GNUNET_PACKED;
82
83   /**
84    * Layer for the request, in NBO.
85    */
86   uint16_t layer GNUNET_PACKED;
87
88   /**
89    * Unique (random) identifier this peer will use to
90    * identify the finger (in future messages).
91    */
92   struct GNUNET_HashCode finger_id;
93
94 };
95
96
97 /**
98  * Response to a `struct FingerSetupMessage`.
99  */
100 struct FingerSetupResponseMessage
101 {
102   /**
103    * Type: #GNUNET_MESSAGE_TYPE_WDHT_FINGER_SETUP_RESPONSE
104    */
105   struct GNUNET_MessageHeader header;
106
107   /**
108    * Zero, for alignment.
109    */
110   uint32_t reserved GNUNET_PACKED;
111
112   /**
113    * Unique (random) identifier this peer will use to
114    * identify the finger (in future messages).
115    */
116   struct GNUNET_HashCode finger_id;
117
118   /**
119    * Random location in the respective layer where the
120    * random path of the finger setup terminated.
121    */
122   struct GNUNET_HashCode location;
123
124 };
125
126
127 /**
128  * Response to an event that causes a finger to die.
129  */
130 struct FingerDestroyMessage
131 {
132   /**
133    * Type: #GNUNET_MESSAGE_TYPE_WDHT_FINGER_DESTROY
134    */
135   struct GNUNET_MessageHeader header;
136
137   /**
138    * Zero, for alignment.
139    */
140   uint32_t reserved GNUNET_PACKED;
141
142   /**
143    * Unique (random) identifier this peer will use to
144    * identify the finger (in future messages).
145    */
146   struct GNUNET_HashCode finger_id;
147
148 };
149
150
151 /**
152  * Send a message along a finger.
153  */
154 struct FingerRouteMessage
155 {
156   /**
157    * Type: #GNUNET_MESSAGE_TYPE_WDHT_FINGER_ROUTE
158    */
159   struct GNUNET_MessageHeader header;
160
161   /**
162    * Zero, for alignment.
163    */
164   uint32_t reserved GNUNET_PACKED;
165
166   /**
167    * Unique (random) identifier this peer will use to
168    * identify the finger (in future messages).
169    */
170   struct GNUNET_HashCode finger_id;
171
172   /* followed by payload to send along the finger */
173 };
174
175
176 /**
177  * P2P PUT message
178  */
179 struct PeerPutMessage
180 {
181   /**
182    * Type: #GNUNET_MESSAGE_TYPE_WDHT_P2P_PUT
183    */
184   struct GNUNET_MessageHeader header;
185
186   /**
187    * Processing options
188    */
189   uint32_t options GNUNET_PACKED;
190
191   /**
192    * Content type.
193    */
194   uint32_t block_type GNUNET_PACKED;
195
196   /**
197    * Hop count
198    */
199   uint32_t hop_count GNUNET_PACKED;
200
201   /**
202    * Replication level for this message
203    * In the current implementation, this value is not used.
204    */
205   uint32_t desired_replication_level GNUNET_PACKED;
206
207   /**
208    * Length of the PUT path that follows (if tracked).
209    */
210   uint32_t put_path_length GNUNET_PACKED;
211
212   /**
213    * When does the content expire?
214    */
215   struct GNUNET_TIME_AbsoluteNBO expiration_time;
216
217   /**
218    * The key to store the value under.
219    */
220   struct GNUNET_HashCode key GNUNET_PACKED;
221
222   /* put path (if tracked) */
223
224   /* Payload */
225
226 };
227
228 /**
229  * P2P GET message
230  */
231 struct PeerGetMessage
232 {
233   /**
234    * Type: #GNUNET_MESSAGE_TYPE_WDHT_P2P_GET
235    */
236   struct GNUNET_MessageHeader header;
237
238   /**
239    * Processing options
240    */
241   uint32_t options GNUNET_PACKED;
242
243   /**
244    * Desired content type.
245    */
246   uint32_t block_type GNUNET_PACKED;
247
248   /**
249    * Hop count
250    */
251   uint32_t hop_count GNUNET_PACKED;
252
253   /**
254    * Desired replication level for this request.
255    * In the current implementation, this value is not used.
256    */
257   uint32_t desired_replication_level GNUNET_PACKED;
258
259   /**
260    * Total number of peers in get path.
261    */
262   unsigned int get_path_length;
263
264   /**
265    * The key we are looking for.
266    */
267   struct GNUNET_HashCode key;
268
269   /* Get path. */
270   /* struct GNUNET_PeerIdentity[]*/
271 };
272
273
274 /**
275  * P2P Result message
276  */
277 struct PeerGetResultMessage
278 {
279   /**
280    * Type: #GNUNET_MESSAGE_TYPE_WDHT_P2P_GET_RESULT
281    */
282   struct GNUNET_MessageHeader header;
283
284   /**
285    * The type for the data.
286    */
287   uint32_t type GNUNET_PACKED;
288
289   /**
290    * Number of peers recorded in the outgoing path from source to the
291    * stored location of this message.
292    */
293   uint32_t put_path_length GNUNET_PACKED;
294
295   /**
296    * Length of the GET path that follows (if tracked).
297    */
298   uint32_t get_path_length GNUNET_PACKED;
299
300   /**
301    * Peer which queried for get and should get the result.
302    */
303   struct GNUNET_PeerIdentity querying_peer;
304
305   /**
306    * When does the content expire?
307    */
308   struct GNUNET_TIME_Absolute expiration_time;
309
310   /**
311    * The key of the corresponding GET request.
312    */
313   struct GNUNET_HashCode key;
314
315   /* put path (if tracked) */
316
317   /* get path (if tracked) */
318
319   /* Payload */
320
321 };
322
323 GNUNET_NETWORK_STRUCT_END
324
325 /**
326  * Entry in friend_peermap.
327  */
328 struct FriendInfo;
329
330
331 /**
332  * Information we keep per trail.
333  */
334 struct Trail
335 {
336
337   /**
338    * MDLL entry in the list of all trails with the same predecessor.
339    */
340   struct Tail *prev_succ;
341
342   /**
343    * MDLL entry in the list of all trails with the same predecessor.
344    */
345   struct Tail *next_succ;
346
347   /**
348    * MDLL entry in the list of all trails with the same predecessor.
349    */
350   struct Tail *prev_pred;
351
352   /**
353    * MDLL entry in the list of all trails with the same predecessor.
354    */
355   struct Tail *next_pred;
356
357   /**
358    * Our predecessor in the trail, NULL if we are initiator (?).
359    */
360   struct FriendInfo *pred;
361
362   /**
363    * Our successor in the trail, NULL if we are the last peer.
364    */
365   struct FriendInfo *succ;
366
367   /**
368    * Identifier of the trail with the predecessor.
369    */
370   struct GNUNET_HashCode pred_id;
371
372   /**
373    * Identifier of the trail with the successor.
374    */
375   struct GNUNET_HashCode succ_id;
376
377   /**
378    * When does this trail expire.
379    */
380   struct GNUNET_TIME_Absolute expiration_time;
381
382   /**
383    * Location of this trail in the heap.
384    */
385   struct GNUNET_CONTAINER_HeapNode *hn;
386
387 };
388
389
390 /**
391  *  Entry in friend_peermap.
392  */
393 struct FriendInfo
394 {
395   /**
396    * Friend Identity
397    */
398   struct GNUNET_PeerIdentity id;
399
400   struct Tail *pred_head;
401
402   struct Tail *pred_tail;
403
404   struct Tail *succ_head;
405
406   struct Tail *succ_tail;
407
408   /**
409    * Core handle for sending messages to this friend.
410    */
411   struct GNUNET_MQ_Handle *mq;
412
413 };
414
415
416
417 /**
418  * Task to timeout trails that have expired.
419  */
420 static struct GNUNET_SCHEDULER_Task *trail_timeout_task;
421
422 /**
423  * Task to perform random walks.
424  */
425 static struct GNUNET_SCHEDULER_Task *random_walk_task;
426
427 /**
428  * Identity of this peer.
429  */
430 static struct GNUNET_PeerIdentity my_identity;
431
432 /**
433  * Peer map of all the fingers of a peer
434  */
435 static struct GNUNET_CONTAINER_MultiPeerMap *fingers_peermap;
436
437 /**
438  * Peer map of all the successors of a peer
439  */
440 static struct GNUNET_CONTAINER_MultiPeerMap *successors_peermap;
441
442 /**
443  * Tail map, mapping tail identifiers to `struct Trail`s
444  */
445 static struct GNUNET_CONTAINER_MultiHashMap *tail_map;
446
447 /**
448  * Tail heap, organizing trails by expiration time.
449  */
450 static struct GNUNET_CONTAINER_Heap *tail_heap;
451
452 /**
453  * Handle to CORE.
454  */
455 static struct GNUNET_CORE_Handle *core_api;
456
457
458 /**
459  * Handle the put request from the client.
460  *
461  * @param key Key for the content
462  * @param block_type Type of the block
463  * @param options Routing options
464  * @param desired_replication_level Desired replication count
465  * @param expiration_time When does the content expire
466  * @param data Content to store
467  * @param data_size Size of content @a data in bytes
468  */
469 void
470 GDS_NEIGHBOURS_handle_put (const struct GNUNET_HashCode *key,
471                            enum GNUNET_BLOCK_Type block_type,
472                            enum GNUNET_DHT_RouteOption options,
473                            uint32_t desired_replication_level,
474                            struct GNUNET_TIME_Absolute expiration_time,
475                            const void *data, size_t data_size)
476 {
477 }
478
479
480 /**
481  * Handle the get request from the client file. If I am destination do
482  * datacache put and return. Else find the target friend and forward message
483  * to it.
484  *
485  * @param key Key for the content
486  * @param block_type Type of the block
487  * @param options Routing options
488  * @param desired_replication_level Desired replication count
489  */
490 void
491 GDS_NEIGHBOURS_handle_get (const struct GNUNET_HashCode *key,
492                            enum GNUNET_BLOCK_Type block_type,
493                            enum GNUNET_DHT_RouteOption options,
494                            uint32_t desired_replication_level)
495 {
496 }
497
498
499
500 /**
501  * Send the get result to requesting client.
502  *
503  * @param key Key of the requested data.
504  * @param type Block type
505  * @param target_peer Next peer to forward the message to.
506  * @param source_peer Peer which has the data for the key.
507  * @param put_path_length Number of peers in @a put_path
508  * @param put_path Path taken to put the data at its stored location.
509  * @param get_path_length Number of peers in @a get_path
510  * @param get_path Path taken to reach to the location of the key.
511  * @param expiration When will this result expire?
512  * @param data Payload to store
513  * @param data_size Size of the @a data
514  */
515 void
516 GDS_NEIGHBOURS_send_get_result (const struct GNUNET_HashCode *key,
517                                 enum GNUNET_BLOCK_Type type,
518                                 const struct GNUNET_PeerIdentity *target_peer,
519                                 const struct GNUNET_PeerIdentity *source_peer,
520                                 unsigned int put_path_length,
521                                 const struct GNUNET_PeerIdentity *put_path,
522                                 unsigned int get_path_length,
523                                 const struct GNUNET_PeerIdentity *get_path,
524                                 struct GNUNET_TIME_Absolute expiration,
525                                 const void *data, size_t data_size)
526 {
527 }
528
529
530 /**
531  * Method called whenever a peer disconnects.
532  *
533  * @param cls closure
534  * @param peer peer identity this notification is about
535  */
536 static void
537 handle_core_disconnect (void *cls,
538                         const struct GNUNET_PeerIdentity *peer)
539 {
540   struct FriendInfo *remove_friend;
541
542   /* If disconnected to own identity, then return. */
543   if (0 == memcmp (&my_identity,
544                    peer,
545                    sizeof (struct GNUNET_PeerIdentity)))
546     return;
547
548   if (NULL == (remove_friend =
549                GNUNET_CONTAINER_multipeermap_get (friend_peermap,
550                                                   peer)))
551   {
552     GNUNET_break (0);
553     return;
554   }
555
556   GNUNET_assert (GNUNET_YES ==
557                  GNUNET_CONTAINER_multipeermap_remove (friend_peermap,
558                                                        peer,
559                                                        remove_friend));
560   /* FIXME: do stuff */
561   GNUNET_MQ_destroy (remove_friend->mq);
562   GNUNET_free (remove_friend);
563   if (0 ==
564       GNUNET_CONTAINER_multipeermap_size (friend_peermap))
565   {
566     GNUNET_SCHEDULER_cancel (random_walk_task);
567     random_walk_task = NULL;
568   }
569 }
570
571
572 /**
573  * Initiate a random walk.
574  *
575  * @param cls NULL
576  * @param tc unused
577  */
578 static void
579 do_random_walk (void *cls,
580                 const struct GNUNET_SCHEDULER_TaskContext *tc)
581 {
582   struct FriendInfo *friend;
583   struct GNUNET_MQ_Envelope *env;
584   struct FingerSetupMessage *fsm;
585
586   friend = NULL; // FIXME: pick at random...
587   env = GNUNET_MQ_msg (fsm,
588                        GNUNET_MESSAGE_TYPE_WDHT_FINGER_SETUP);
589   fsm->hops_task = htons (0);
590   fsm->layer = htons (0); // FIXME: not always 0...
591   GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_NONCE,
592                                     &fsm->finger_id);
593   GNUNET_MQ_send (friend->mq,
594                   env);
595 }
596
597
598 /**
599  * Method called whenever a peer connects.
600  *
601  * @param cls closure
602  * @param peer_identity peer identity this notification is about
603  */
604 static void
605 handle_core_connect (void *cls,
606                      const struct GNUNET_PeerIdentity *peer_identity)
607 {
608   struct FriendInfo *friend;
609
610   /* Check for connect to self message */
611   if (0 == memcmp (&my_identity,
612                    peer_identity,
613                    sizeof (struct GNUNET_PeerIdentity)))
614     return;
615
616   /* If peer already exists in our friend_peermap, then exit. */
617   if (GNUNET_YES ==
618       GNUNET_CONTAINER_multipeermap_contains (friend_peermap,
619                                               peer_identity))
620   {
621     GNUNET_break (0);
622     return;
623   }
624
625   friend = GNUNET_new (struct FriendInfo);
626   friend->id = *peer_identity;
627   friend->mq = GNUNET_CORE_mq_create (core_api,
628                                       peer_identity);
629   GNUNET_assert (GNUNET_OK ==
630                  GNUNET_CONTAINER_multipeermap_put (friend_peermap,
631                                                     peer_identity,
632                                                     friend,
633                                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
634   /* do work? */
635
636   if (NULL == random_walk_task)
637   {
638     /* start random walks! */
639     random_walk_task = GNUNET_SCHEDULER_add_now (&do_random_walk,
640                                                  NULL);
641   }
642 }
643
644
645 /**
646  * To be called on core init/fail.
647  *
648  * @param cls service closure
649  * @param identity the public identity of this peer
650  */
651 static void
652 core_init (void *cls,
653            const struct GNUNET_PeerIdentity *identity)
654 {
655   my_identity = *identity;
656 }
657
658
659 /**
660  * Handle a `struct FingerSetupMessage` from a GNUNET_MESSAGE_TYPE_WDHT_FINGER_SETUP
661  * message.
662  *
663  * @param cls closure (NULL)
664  * @param peer sender identity
665  * @param message the setup message
666  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
667  */
668 static int
669 handle_dht_p2p_finger_setup (void *cls,
670                              const struct GNUNET_PeerIdentity *peer,
671                              const struct GNUNET_MessageHeader *message)
672 {
673   const struct FingerSetupMessage *fsm;
674
675   fsm = (const struct FingerSetupMessage *) message;
676
677   /*
678    * Steps :
679    *  1 check if the hops_taken is < to log(honest node)
680    *  1.a.1 if true : increments the hops_taken
681    *  1.a.2 send the same structure
682    *  1.b if false : drop the message
683    */
684
685   return GNUNET_OK;
686 }
687
688 /**
689  * Handle a `struct FingerSetupResponseMessage` from a GNUNET_MESSAGE_TYPE_WDHT_FINGER_SETUP_RESPONSE
690  * message.
691  *
692  * @param cls closure (NULL)
693  * @param peer sender identity
694  * @param message the setup response message
695  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
696  */
697 static int
698 handle_dht_p2p_finger_setup_response (void *cls,
699                              const struct GNUNET_PeerIdentity *peer,
700                              const struct GNUNET_MessageHeader *message)
701 {
702   const struct FingerSetupResponseMessage *fsrm;
703
704   fsm = (const struct FingerSetupResponseMessage *) message;
705
706   /*
707    * Steps :
708    *  1 check if we are the correct layer
709    *  1.a if true : add the return value in the db structure
710    *  1.b if true : do nothing
711    */
712
713   return GNUNET_OK;
714 }
715
716
717 /**
718  * Handle a `struct FingerDestroyMessage`.
719  *
720  * @param cls closure (NULL)
721  * @param peer sender identity
722  * @param message the finger destroy message
723  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
724  */
725 static int
726 handle_dht_p2p_finger_destroy (void *cls,
727                              const struct GNUNET_PeerIdentity *peer,
728                              const struct GNUNET_MessageHeader *message)
729 {
730   const struct FingerDestroyMessage *fdm;
731
732   fdm = (const struct FingerDestroyMessage *) message;
733
734   /*
735    * Steps :
736    *  1 check if message comme from a trail
737    *  1.a.1 if true: send the destroy message to the rest trail
738    *  1.a.2 clean the trail structure
739    *  1.a.3 did i have to remove the trail and ID from the db structure?
740    *  1.b if false: do nothing
741    */
742
743   return GNUNET_OK;
744 }
745
746 /**
747  * Handle a `struct FingerRouteMessage`.
748  *
749  * @param cls closure (NULL)
750  * @param peer sender identity
751  * @param message the finger route message
752  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
753  */
754 static int
755 handle_dht_p2p_finger_route (void *cls,
756                              const struct GNUNET_PeerIdentity *peer,
757                              const struct GNUNET_MessageHeader *message)
758 {
759   const struct FingerRouteMessage *frm;
760
761   frm = (const struct FingerRouteMessage *) message;
762   /* FIXME: check the size of the message */
763
764   /*
765    * steps :
766    *  1 find the good trail
767    *  2 send the finger route message
768    */
769
770   return GNUNET_OK;
771 }
772
773 /**
774  * Handle a `struct FingerSetupMessage` from a GNUNET_MESSAGE_TYPE_WDHT_NEIGHBOUR_FIND
775  * message.
776  *
777  * @param cls closure (NULL)
778  * @param peer sender identity
779  * @param message the finger setup message
780  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
781  */
782 static int
783 handle_dht_p2p_neighbour_find (void *cls,
784                              const struct GNUNET_PeerIdentity *peer,
785                              const struct GNUNET_MessageHeader *message)
786 {
787   const struct FingerSetupMessage *fsm;
788
789   fsm = (const struct FingerSetupMessage *) message;
790
791   return GNUNET_OK;
792 }
793
794 /**
795  * Handle a `struct FingerSetupResponseMessage` from a GNUNET_MESSAGE_TYPE_WDHT_NEIGHBOUR_FIND
796  * message.
797  *
798  * @param cls closure (NULL)
799  * @param peer sender identity
800  * @param message the finger setup response message
801  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
802  */
803 static int
804 handle_dht_p2p_neighbour_found (void *cls,
805                              const struct GNUNET_PeerIdentity *peer,
806                              const struct GNUNET_MessageHeader *message)
807 {
808   const struct FingerSetupResponseMessage *fsrm;
809
810   fsrm = (const struct FingerSetupResponseMessage *) message;
811
812   return GNUNET_OK;
813 }
814
815 /**
816  * Handle a `struct PeerGetMessage`.
817  *
818  * @param cls closure (NULL)
819  * @param peer sender identity
820  * @param message the peer get message
821  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
822  */
823 static int
824 handle_dht_p2p_peer_get (void *cls,
825                              const struct GNUNET_PeerIdentity *peer,
826                              const struct GNUNET_MessageHeader *message)
827 {
828   const struct PeerGetMessage *pgm;
829
830   pgm = (const struct PeerGetMessage *) message;
831
832      /*
833     * steps :
834     *   1 extract the result
835     *   2 save the peer
836     *   3 send it using the good trail
837     *
838     * What do i do when i don't have the key/value?
839     */
840
841   return GNUNET_OK;
842 }
843
844 /**
845  * Handle a `struct PeerGetResultMessage`.
846  *
847  * @param cls closure (NULL)
848  * @param peer sender identity
849  * @param message the peer get result message
850  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
851  */
852 static int
853 handle_dht_p2p_peer_get_result (void *cls,
854                              const struct GNUNET_PeerIdentity *peer,
855                              const struct GNUNET_MessageHeader *message)
856 {
857   const struct PeerGetResultMessage *pgrm;
858
859   pgrm = (const struct PeerGetResultMessage *) message;
860
861   /*
862    * steps :
863    *   1 extract the result
864    *   2 create a peerGetResult struct
865    *   3 send it using the good trail
866    *
867    * What do i do when i don't have the key/value?
868    */
869
870   return GNUNET_OK;
871 }
872
873
874 /**
875  * Handle a `struct PeerPutMessage`.
876  *
877  * @param cls closure (NULL)
878  * @param peer sender identity
879  * @param message the peer put message
880  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
881  */
882 static int
883 handle_dht_p2p_peer_put (void *cls,
884                              const struct GNUNET_PeerIdentity *peer,
885                              const struct GNUNET_MessageHeader *message)
886 {
887   const struct PeerGetResultMessage *pgrm;
888
889   pgrm = (const struct PeerGetResultMessage *) message;
890
891   /*
892    * steps :
893    * 1 check the size of the message
894    * 2 use the API to add the value in the "database". Check on the xdht file, how to do it.
895    * 3 Did i a have to return a notification or did i have to return GNUNET_[OK|SYSERR]?
896    */
897   return GNUNET_OK;
898 }
899
900
901 /**
902  * Initialize neighbours subsystem.
903  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
904  */
905 int
906 GDS_NEIGHBOURS_init (void)
907 {
908   static const struct GNUNET_CORE_MessageHandler core_handlers[] = {
909     { &handle_dht_p2p_finger_setup,
910       GNUNET_MESSAGE_TYPE_WDHT_FINGER_SETUP,
911       sizeof (struct FingerSetupMessage) },
912     { &handle_dht_p2p_finger_setup_response,
913       GNUNET_MESSAGE_TYPE_WDHT_FINGER_SETUP_RESPONSE,
914       sizeof (struct FingerSetupResponseMessage) },
915     { &handle_dht_p2p_finger_destroy,
916       GNUNET_MESSAGE_TYPE_WDHT_FINGER_DESTROY,
917       sizeof (struct FingerDestroyMessage) },
918     { &handle_dht_p2p_finger_route,
919       GNUNET_MESSAGE_TYPE_WDHT_FINGER_ROUTE,
920       0},
921     { &handle_dht_p2p_neighbour_find,
922       GNUNET_MESSAGE_TYPE_WDHT_NEIGHBOUR_FIND,
923       sizeof (struct FingerSetupMessage) },
924     { &handle_dht_p2p_neighbour_found,
925       GNUNET_MESSAGE_TYPE_WDHT_NEIGHBOUR_FOUND,
926       sizeof (struct FingerSetupResponseMessage) },
927     { &handle_dht_p2p_peer_get,
928       GNUNET_MESSAGE_TYPE_WDHT_GET,
929       sizeof (struct PeerGetMessage) },
930     { &handle_dht_p2p_peer_get_result,
931       GNUNET_MESSAGE_TYPE_WDHT_GET_RESULT,
932       0},
933     { &handle_dht_p2p_peer_put,
934       GNUNET_MESSAGE_TYPE_WDHT_PUT,
935       0},
936     {NULL, 0, 0}
937   };
938
939   core_api =
940     GNUNET_CORE_connect (GDS_cfg, NULL,
941                          &core_init,
942                          &handle_core_connect,
943                          &handle_core_disconnect,
944                          NULL, GNUNET_NO,
945                          NULL, GNUNET_NO,
946                          core_handlers);
947
948   if (NULL == core_api)
949     return GNUNET_SYSERR;
950
951   fingers_peermap = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_NO);
952   successors_peermap = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_NO);
953
954   return GNUNET_OK;
955 }
956
957
958 /**
959  * Shutdown neighbours subsystem.
960  */
961 void
962 GDS_NEIGHBOURS_done (void)
963 {
964   if (NULL == core_api)
965     return;
966   GNUNET_CORE_disconnect (core_api);
967   core_api = NULL;
968
969   GNUNET_assert (0 == GNUNET_CONTAINER_multipeermap_size (friend_peermap));
970   GNUNET_CONTAINER_multipeermap_destroy (friend_peermap);
971   friend_peermap = NULL;
972 }
973
974
975 /**
976  * Get my identity
977  *
978  * @return my identity
979  */
980 struct GNUNET_PeerIdentity
981 GDS_NEIGHBOURS_get_my_id (void)
982 {
983   return my_identity;
984 }
985
986 /* end of gnunet-service-wdht_neighbours.c */