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