- sync
[oweals/gnunet.git] / src / mesh / gnunet-service-mesh_dht.c
1 /*
2      This file is part of GNUnet.
3      (C) 2013 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 #include "platform.h"
23 #include "gnunet_util_lib.h"
24
25 #include "gnunet_dht_service.h"
26
27 #include "gnunet-service-mesh_dht.h"
28 #include "gnunet-service-mesh_peer.h"
29
30 #define MESH_DEBUG_DHT          GNUNET_NO
31
32 #if MESH_DEBUG_DHT
33 #define DEBUG_DHT(...) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
34 #else
35 #define DEBUG_DHT(...)
36 #endif
37
38 /******************************************************************************/
39 /********************************   STRUCTS  **********************************/
40 /******************************************************************************/
41
42
43
44
45 /******************************************************************************/
46 /*******************************   GLOBALS  ***********************************/
47 /******************************************************************************/
48
49 /**
50  * Handle to use DHT.
51  */
52 static struct GNUNET_DHT_Handle *dht_handle;
53
54 /**
55  * How often to PUT own ID in the DHT.
56  */
57 static struct GNUNET_TIME_Relative id_announce_time;
58
59 /**
60  * DHT replication level, see DHT API: GNUNET_DHT_get_start, GNUNET_DHT_put.
61  */
62 static unsigned long long dht_replication_level;
63
64 /**
65  * Task to periodically announce itself in the network.
66  */
67 static GNUNET_SCHEDULER_TaskIdentifier announce_id_task;
68
69 /**
70  * Own ID (full value).
71  */
72 static struct GNUNET_PeerIdentity *id;
73
74 /**
75  * Own private key.
76  */
77 static struct GNUNET_CRYPTO_EccPrivateKey *private_key;
78
79
80 /******************************************************************************/
81 /********************************   STATIC  ***********************************/
82 /******************************************************************************/
83
84
85 /**
86  * Periodically announce self id in the DHT
87  *
88  * @param cls closure
89  * @param tc task context
90  */
91 static void
92 announce_id (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
93 {
94   struct PBlock block;
95   struct GNUNET_HashCode phash;
96
97   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
98   {
99     announce_id_task = GNUNET_SCHEDULER_NO_TASK;
100     return;
101   }
102   /* TODO
103    * - Set data expiration in function of X
104    * - Adapt X to churn
105    */
106   DEBUG_DHT ("DHT_put for ID %s started.\n", GNUNET_i2s (id));
107
108   block.id = *id;
109   GNUNET_CRYPTO_hash (id, sizeof (struct GNUNET_PeerIdentity), &phash);
110   GNUNET_DHT_put (dht_handle,   /* DHT handle */
111                   &phash,       /* Key to use */
112                   dht_replication_level,     /* Replication level */
113                   GNUNET_DHT_RO_RECORD_ROUTE | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,    /* DHT options */
114                   GNUNET_BLOCK_TYPE_MESH_PEER,       /* Block type */
115                   sizeof (block),  /* Size of the data */
116                   (const char *) &block, /* Data itself */
117                   GNUNET_TIME_UNIT_FOREVER_ABS,  /* Data expiration */
118                   GNUNET_TIME_UNIT_FOREVER_REL, /* Retry time */
119                   NULL,         /* Continuation */
120                   NULL);        /* Continuation closure */
121   announce_id_task =
122       GNUNET_SCHEDULER_add_delayed (id_announce_time, &announce_id, cls);
123 }
124
125
126 /******************************************************************************/
127 /********************************    API    ***********************************/
128 /******************************************************************************/
129
130 /**
131  * Initialize the DHT subsystem.
132  *
133  * @param c Configuration.
134  * @param peer_id Local peer ID (must remain valid during all execution time).
135  */
136 void
137 GMD_init (const struct GNUNET_CONFIGURATION_Handle *c,
138           struct GNUNET_PeerIdentity *peer_id)
139 {
140   id = peer_id;
141   if (GNUNET_OK !=
142       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "DHT_REPLICATION_LEVEL",
143                                              &dht_replication_level))
144   {
145     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
146                                "MESH", "DHT_REPLICATION_LEVEL", "USING DEFAULT");
147     dht_replication_level = 3;
148   }
149
150   if (GNUNET_OK !=
151       GNUNET_CONFIGURATION_get_value_time (c, "MESH", "ID_ANNOUNCE_TIME",
152                                            &id_announce_time))
153   {
154     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
155                                "MESH", "ID_ANNOUNCE_TIME", "MISSING");
156     GNUNET_SCHEDULER_shutdown ();
157     return;
158   }
159
160   dht_handle = GNUNET_DHT_connect (c, 64);
161   if (NULL == dht_handle)
162   {
163     GNUNET_break (0);
164   }
165
166   announce_id_task = GNUNET_SCHEDULER_add_now (&announce_id, NULL);
167 }
168
169
170 /**
171  * Shut down the DHT subsystem.
172  */
173 void
174 GMD_shutdown(void )
175 {
176   if (dht_handle != NULL)
177   {
178     GNUNET_DHT_disconnect (dht_handle);
179     dht_handle = NULL;
180   }
181   if (GNUNET_SCHEDULER_NO_TASK != announce_id_task)
182   {
183     GNUNET_SCHEDULER_cancel (announce_id_task);
184     announce_id_task = GNUNET_SCHEDULER_NO_TASK;
185   }
186 }