ea1cd77bdfb86a4e63ea906928ccdbc27b7a3385
[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
374
375 /**
376  *  Entry in friend_peermap.
377  */
378 struct FriendInfo
379 {
380   /**
381    * Friend Identity
382    */
383   struct GNUNET_PeerIdentity id;
384
385   struct Tail *pred_head;
386
387   struct Tail *pred_tail;
388
389   struct Tail *succ_head;
390
391   struct Tail *succ_tail;
392
393   /**
394    * Core handle for sending messages to this friend.
395    * FIXME: use MQ?
396    */
397   struct GNUNET_CORE_TransmitHandle *th;
398
399 };
400
401
402
403 /**
404  * Task to timeout trails that have expired.
405  */
406 static struct GNUNET_SCHEDULER_Task *trail_timeout_task;
407
408 /**
409  * Identity of this peer.
410  */
411 static struct GNUNET_PeerIdentity my_identity;
412
413 /**
414  * Peer map of all the friends of a peer
415  */
416 static struct GNUNET_CONTAINER_MultiPeerMap *friend_peermap;
417
418 /**
419  * Tail map, mapping tail identifiers to `struct Trail`s
420  */
421 static struct GNUNET_CONTAINER_MultiHashMap *tail_map;
422
423 /**
424  * Tail heap, organizing trails by expiration time.
425  */
426 static struct GNUNET_CONTAINER_Heap *tail_heap;
427
428 /**
429  * Handle to CORE.
430  */
431 static struct GNUNET_CORE_Handle *core_api;
432
433
434 /**
435  * Handle the put request from the client.
436  *
437  * @param key Key for the content
438  * @param block_type Type of the block
439  * @param options Routing options
440  * @param desired_replication_level Desired replication count
441  * @param expiration_time When does the content expire
442  * @param data Content to store
443  * @param data_size Size of content @a data in bytes
444  */
445 void
446 GDS_NEIGHBOURS_handle_put (const struct GNUNET_HashCode *key,
447                            enum GNUNET_BLOCK_Type block_type,
448                            enum GNUNET_DHT_RouteOption options,
449                            uint32_t desired_replication_level,
450                            struct GNUNET_TIME_Absolute expiration_time,
451                            const void *data, size_t data_size)
452 {
453 }
454
455
456 /**
457  * Handle the get request from the client file. If I am destination do
458  * datacache put and return. Else find the target friend and forward message
459  * to it.
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  */
466 void
467 GDS_NEIGHBOURS_handle_get (const struct GNUNET_HashCode *key,
468                            enum GNUNET_BLOCK_Type block_type,
469                            enum GNUNET_DHT_RouteOption options,
470                            uint32_t desired_replication_level)
471 {
472 }
473
474
475
476 /**
477  * Send the get result to requesting client.
478  *
479  * @param key Key of the requested data.
480  * @param type Block type
481  * @param target_peer Next peer to forward the message to.
482  * @param source_peer Peer which has the data for the key.
483  * @param put_path_length Number of peers in @a put_path
484  * @param put_path Path taken to put the data at its stored location.
485  * @param get_path_length Number of peers in @a get_path
486  * @param get_path Path taken to reach to the location of the key.
487  * @param expiration When will this result expire?
488  * @param data Payload to store
489  * @param data_size Size of the @a data
490  */
491 void
492 GDS_NEIGHBOURS_send_get_result (const struct GNUNET_HashCode *key,
493                                 enum GNUNET_BLOCK_Type type,
494                                 const struct GNUNET_PeerIdentity *target_peer,
495                                 const struct GNUNET_PeerIdentity *source_peer,
496                                 unsigned int put_path_length,
497                                 const struct GNUNET_PeerIdentity *put_path,
498                                 unsigned int get_path_length,
499                                 const struct GNUNET_PeerIdentity *get_path,
500                                 struct GNUNET_TIME_Absolute expiration,
501                                 const void *data, size_t data_size)
502 {
503 }
504
505
506 /**
507  * Method called whenever a peer disconnects.
508  *
509  * @param cls closure
510  * @param peer peer identity this notification is about
511  */
512 static void
513 handle_core_disconnect (void *cls,
514                         const struct GNUNET_PeerIdentity *peer)
515 {
516   struct FriendInfo *remove_friend;
517
518   /* If disconnected to own identity, then return. */
519   if (0 == memcmp (&my_identity,
520                    peer,
521                    sizeof (struct GNUNET_PeerIdentity)))
522     return;
523
524   if (NULL == (remove_friend =
525                GNUNET_CONTAINER_multipeermap_get (friend_peermap,
526                                                   peer)))
527   {
528     GNUNET_break (0);
529     return;
530   }
531
532   GNUNET_assert (GNUNET_YES ==
533                  GNUNET_CONTAINER_multipeermap_remove (friend_peermap,
534                                                        peer,
535                                                        remove_friend));
536   /* FIXME: do stuff */
537 }
538
539
540 /**
541  * Method called whenever a peer connects.
542  *
543  * @param cls closure
544  * @param peer_identity peer identity this notification is about
545  */
546 static void
547 handle_core_connect (void *cls,
548                      const struct GNUNET_PeerIdentity *peer_identity)
549 {
550   struct FriendInfo *friend;
551
552   /* Check for connect to self message */
553   if (0 == memcmp (&my_identity,
554                    peer_identity,
555                    sizeof (struct GNUNET_PeerIdentity)))
556     return;
557
558   /* If peer already exists in our friend_peermap, then exit. */
559   if (GNUNET_YES ==
560       GNUNET_CONTAINER_multipeermap_contains (friend_peermap,
561                                               peer_identity))
562   {
563     GNUNET_break (0);
564     return;
565   }
566
567   friend = GNUNET_new (struct FriendInfo);
568   friend->id = *peer_identity;
569
570   GNUNET_assert (GNUNET_OK ==
571                  GNUNET_CONTAINER_multipeermap_put (friend_peermap,
572                                                     peer_identity,
573                                                     friend,
574                                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
575   /* do work? */
576 }
577
578
579 /**
580  * To be called on core init/fail.
581  *
582  * @param cls service closure
583  * @param identity the public identity of this peer
584  */
585 static void
586 core_init (void *cls,
587            const struct GNUNET_PeerIdentity *identity)
588 {
589   my_identity = *identity;
590 }
591
592
593 /**
594  * Handle a `struct FingerSetupMessage`.
595  *
596  * @param cls closure (NULL)
597  * @param peer sender identity
598  * @param message the setup message
599  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
600  */
601 static int
602 handle_dht_p2p_finger_setup (void *cls,
603                              const struct GNUNET_PeerIdentity *peer,
604                              const struct GNUNET_MessageHeader *message)
605 {
606   const struct FingerSetupMessage *fsm;
607
608   fsm = (const struct FingerSetupMessage *) message;
609
610   return GNUNET_OK;
611 }
612
613 /**
614  * Handle a `struct FingerSetupResponseMessage`.
615  *
616  * @param cls closure (NULL)
617  * @param peer sender identity
618  * @param message the setup response message
619  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
620  */
621 static int
622 handle_dht_p2p_finger_setup_response (void *cls,
623                              const struct GNUNET_PeerIdentity *peer,
624                              const struct GNUNET_MessageHeader *message)
625 {
626   const struct FingerSetupResponseMessage *fsrm;
627
628   fsm = (const struct  *) message;
629
630   return GNUNET_OK;
631 }
632
633
634 /**
635  * Handle a `struct FingerDestroyMessage`.
636  *
637  * @param cls closure (NULL)
638  * @param peer sender identity
639  * @param message the finger destroy message
640  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
641  */
642 static int
643 handle_dht_p2p_finger_destroy (void *cls,
644                              const struct GNUNET_PeerIdentity *peer,
645                              const struct GNUNET_MessageHeader *message)
646 {
647   const struct FingerDestroyMessage *fdm;
648
649   fsm = (const struct  *) message;
650
651   return GNUNET_OK;
652 }
653
654 /**
655  * Handle a `struct FingerRouteMessage`.
656  *
657  * @param cls closure (NULL)
658  * @param peer sender identity
659  * @param message the finger route message
660  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
661  */
662 static int
663 handle_dht_p2p_finger_route (void *cls,
664                              const struct GNUNET_PeerIdentity *peer,
665                              const struct GNUNET_MessageHeader *message)
666 {
667   const struct FingerRouteMessage *frm;
668
669   fsm = (const struct  *) message;
670   /* FIXME: check the size of the message */
671
672   return GNUNET_OK;
673 }
674
675 /**
676  * Handle a `struct FingerRouteMessage`.
677  *
678  * @param cls closure (NULL)
679  * @param peer sender identity
680  * @param message the finger route message
681  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
682  */
683 static int
684 handle_dht_p2p_neighbour_find (void *cls,
685                              const struct GNUNET_PeerIdentity *peer,
686                              const struct GNUNET_MessageHeader *message)
687 {
688   const struct FingerSetupMessage *fsm;
689
690   fsm = (const struct  *) message;
691
692   return GNUNET_OK;
693 }
694
695 /**
696  * Initialize neighbours subsystem.
697  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
698  */
699 int
700 GDS_NEIGHBOURS_init (void)
701 {
702   static const struct GNUNET_CORE_MessageHandler core_handlers[] = {
703     { &handle_dht_p2p_finger_setup,
704       GNUNET_MESSAGE_TYPE_WDHT_FINGER_SETUP,
705       sizeof (struct FingerSetupMessage) },
706     { &handle_dht_p2p_finger_setup_response,
707       GNUNET_MESSAGE_TYPE_WDHT_FINGER_SETUP_RESPONSE,
708       sizeof (struct FingerSetupResponseMessage) },
709     { &handle_dht_p2p_finger_destroy,
710       GNUNET_MESSAGE_TYPE_WDHT_FINGER_DESTROY,
711       sizeof (struct FingerDestroyMessage) },
712     { &handle_dht_p2p_finger_route,
713       GNUNET_MESSAGE_TYPE_WDHT_FINGER_ROUTE,
714       0},
715     { &handle_dht_p2p_neighbour_find,
716       GNUNET_MESSAGE_TYPE_WDHT_NEIGHBOUR_FIND,
717       sizeof (struct FingerSetupMessage) },
718         { &handle_dht_p2p_neighbour_find,
719       GNUNET_MESSAGE_TYPE_WDHT_NEIGHBOUR_FOUND,
720       sizeof (struct FingerSetupMessage) },
721     {NULL, 0, 0}
722   };
723
724   core_api =
725     GNUNET_CORE_connect (GDS_cfg, NULL,
726                          &core_init,
727                          &handle_core_connect,
728                          &handle_core_disconnect,
729                          NULL, GNUNET_NO,
730                          NULL, GNUNET_NO,
731                          core_handlers);
732
733   if (NULL == core_api)
734     return GNUNET_SYSERR;
735
736   friend_peermap = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_NO);
737   return GNUNET_OK;
738 }
739
740
741 /**
742  * Shutdown neighbours subsystem.
743  */
744 void
745 GDS_NEIGHBOURS_done (void)
746 {
747   if (NULL == core_api)
748     return;
749   GNUNET_CORE_disconnect (core_api);
750   core_api = NULL;
751
752   GNUNET_assert (0 == GNUNET_CONTAINER_multipeermap_size (friend_peermap));
753   GNUNET_CONTAINER_multipeermap_destroy (friend_peermap);
754   friend_peermap = NULL;
755 }
756
757
758 /**
759  * Get my identity
760  *
761  * @return my identity
762  */
763 struct GNUNET_PeerIdentity
764 GDS_NEIGHBOURS_get_my_id (void)
765 {
766   return my_identity;
767 }
768
769 /* end of gnunet-service-wdht_neighbours.c */