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