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