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