aboutsummaryrefslogtreecommitdiff
path: root/src/cadet/gnunet-service-cadet_dht.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cadet/gnunet-service-cadet_dht.c')
-rw-r--r--src/cadet/gnunet-service-cadet_dht.c357
1 files changed, 0 insertions, 357 deletions
diff --git a/src/cadet/gnunet-service-cadet_dht.c b/src/cadet/gnunet-service-cadet_dht.c
deleted file mode 100644
index 3df2687de..000000000
--- a/src/cadet/gnunet-service-cadet_dht.c
+++ /dev/null
@@ -1,357 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2013, 2017 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your 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 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/**
21 * @file cadet/gnunet-service-cadet_dht.c
22 * @brief Information we track per peer.
23 * @author Bartlomiej Polot
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "gnunet_util_lib.h"
29#include "gnunet_dht_service.h"
30#include "gnunet_statistics_service.h"
31#include "gnunet-service-cadet.h"
32#include "gnunet-service-cadet_dht.h"
33#include "gnunet-service-cadet_hello.h"
34#include "gnunet-service-cadet_peer.h"
35#include "gnunet-service-cadet_paths.h"
36
37/**
38 * How long do we wait before first announcing our presence to the DHT.
39 * Used to wait for our HELLO to be available. Note that we also get
40 * notifications when our HELLO is ready, so this is just the maximum
41 * we wait for the first notification.
42 */
43#define STARTUP_DELAY GNUNET_TIME_relative_multiply ( \
44 GNUNET_TIME_UNIT_MILLISECONDS, 500)
45
46/**
47 * How long do we wait after we get an updated HELLO before publishing?
48 * Allows for the HELLO to be updated again quickly, for example in
49 * case multiple addresses changed and we got a partial update.
50 */
51#define CHANGE_DELAY GNUNET_TIME_relative_multiply ( \
52 GNUNET_TIME_UNIT_MILLISECONDS, 100)
53
54
55#define LOG(level, ...) GNUNET_log_from (level, "cadet-dht", __VA_ARGS__)
56
57
58/**
59 * Handle for DHT searches.
60 */
61struct GCD_search_handle
62{
63 /**
64 * DHT_GET handle.
65 */
66 struct GNUNET_DHT_GetHandle *dhtget;
67};
68
69
70/**
71 * Handle to use DHT.
72 */
73static struct GNUNET_DHT_Handle *dht_handle;
74
75/**
76 * How often to PUT own ID in the DHT.
77 */
78static struct GNUNET_TIME_Relative id_announce_time;
79
80/**
81 * DHT replication level, see DHT API: #GNUNET_DHT_get_start(), #GNUNET_DHT_put().
82 */
83static unsigned long long dht_replication_level;
84
85/**
86 * Task to periodically announce itself in the network.
87 */
88static struct GNUNET_SCHEDULER_Task *announce_id_task;
89
90/**
91 * Delay for the next ID announce.
92 */
93static struct GNUNET_TIME_Relative announce_delay;
94
95
96/**
97 * Function to process paths received for a new peer addition. The recorded
98 * paths form the initial tunnel, which can be optimized later.
99 * Called on each result obtained for the DHT search.
100 *
101 * @param cls closure
102 * @param exp when will this value expire
103 * @param key key of the result
104 * @param trunc_peer peer preceeding with invalid signature, or NULL
105 * @param get_path path of the get request
106 * @param get_path_length length of @a get_path
107 * @param put_path path of the put request
108 * @param put_path_length length of the @a put_path
109 * @param type type of the result
110 * @param size number of bytes in data
111 * @param data pointer to the result data
112 */
113static void
114dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
115 const struct GNUNET_HashCode *key,
116 const struct GNUNET_PeerIdentity *trunc_peer,
117 const struct GNUNET_DHT_PathElement *get_path,
118 unsigned int get_path_length,
119 const struct GNUNET_DHT_PathElement *put_path,
120 unsigned int put_path_length,
121 enum GNUNET_BLOCK_Type type,
122 size_t size,
123 const void *data)
124{
125 const struct GNUNET_HELLO_Message *hello = data;
126
127 (void) trunc_peer;
128 GCPP_try_path_from_dht (get_path,
129 get_path_length,
130 put_path,
131 put_path_length);
132 if ((size >= sizeof(struct GNUNET_HELLO_Message)) &&
133 (ntohs (hello->header.size) == size) &&
134 (size == GNUNET_HELLO_size (hello)))
135 {
136 struct CadetPeer *peer;
137
138 peer = GCP_get (&put_path[0].pred,
139 GNUNET_YES);
140 LOG (GNUNET_ERROR_TYPE_DEBUG,
141 "Got HELLO for %s\n",
142 GCP_2s (peer));
143 GCP_set_hello (peer,
144 hello);
145 }
146}
147
148
149/**
150 * Periodically announce self id in the DHT
151 *
152 * @param cls closure
153 */
154static void
155announce_id (void *cls)
156{
157 struct GNUNET_HashCode phash;
158 const struct GNUNET_HELLO_Message *hello;
159 size_t size;
160 struct GNUNET_TIME_Absolute expiration;
161 struct GNUNET_TIME_Relative next_put;
162
163 hello = GCH_get_mine ();
164 size = (NULL != hello) ? GNUNET_HELLO_size (hello) : 0;
165 if (0 == size)
166 {
167 expiration = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
168 announce_delay);
169 announce_delay = GNUNET_TIME_STD_BACKOFF (announce_delay);
170 }
171 else
172 {
173 expiration = GNUNET_HELLO_get_last_expiration (hello);
174 announce_delay = GNUNET_TIME_UNIT_SECONDS;
175 }
176
177 /* Call again in id_announce_time, unless HELLO expires first,
178 * but wait at least 1s. */
179 next_put
180 = GNUNET_TIME_absolute_get_remaining (expiration);
181 next_put
182 = GNUNET_TIME_relative_min (next_put,
183 id_announce_time);
184 next_put
185 = GNUNET_TIME_relative_max (next_put,
186 GNUNET_TIME_UNIT_SECONDS);
187 announce_id_task
188 = GNUNET_SCHEDULER_add_delayed (next_put,
189 &announce_id,
190 cls);
191 GNUNET_STATISTICS_update (stats,
192 "# DHT announce",
193 1,
194 GNUNET_NO);
195 memset (&phash,
196 0,
197 sizeof(phash));
198 GNUNET_memcpy (&phash,
199 &my_full_id,
200 sizeof(my_full_id));
201 LOG (GNUNET_ERROR_TYPE_DEBUG,
202 "Announcing my HELLO (%lu bytes) in the DHT\n",
203 (unsigned long) size);
204 GNUNET_DHT_put (dht_handle, /* DHT handle */
205 &phash, /* Key to use */
206 dht_replication_level, /* Replication level */
207 GNUNET_DHT_RO_RECORD_ROUTE
208 | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, /* DHT options */
209 GNUNET_BLOCK_TYPE_DHT_HELLO, /* Block type */
210 size, /* Size of the data */
211 (const char *) hello, /* Data itself */
212 expiration, /* Data expiration */
213 NULL, /* Continuation */
214 NULL); /* Continuation closure */
215}
216
217
218/**
219 * Function called by the HELLO subsystem whenever OUR hello
220 * changes. Re-triggers the DHT PUT immediately.
221 */
222void
223GCD_hello_update ()
224{
225 if (NULL == announce_id_task)
226 return; /* too early */
227 GNUNET_SCHEDULER_cancel (announce_id_task);
228 announce_id_task
229 = GNUNET_SCHEDULER_add_delayed (CHANGE_DELAY,
230 &announce_id,
231 NULL);
232}
233
234
235/**
236 * Initialize the DHT subsystem.
237 *
238 * @param c Configuration.
239 */
240void
241GCD_init (const struct GNUNET_CONFIGURATION_Handle *c)
242{
243 if (GNUNET_OK !=
244 GNUNET_CONFIGURATION_get_value_number (c,
245 "CADET",
246 "DHT_REPLICATION_LEVEL",
247 &dht_replication_level))
248 {
249 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
250 "CADET",
251 "DHT_REPLICATION_LEVEL",
252 "USING DEFAULT");
253 dht_replication_level = 3;
254 }
255
256 if (GNUNET_OK !=
257 GNUNET_CONFIGURATION_get_value_time (c,
258 "CADET",
259 "ID_ANNOUNCE_TIME",
260 &id_announce_time))
261 {
262 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
263 "CADET",
264 "ID_ANNOUNCE_TIME",
265 "MISSING");
266 GNUNET_SCHEDULER_shutdown ();
267 return;
268 }
269
270 dht_handle = GNUNET_DHT_connect (c,
271 64);
272 GNUNET_break (NULL != dht_handle);
273 announce_delay = GNUNET_TIME_UNIT_SECONDS;
274 announce_id_task = GNUNET_SCHEDULER_add_delayed (STARTUP_DELAY,
275 &announce_id,
276 NULL);
277}
278
279
280/**
281 * Shut down the DHT subsystem.
282 */
283void
284GCD_shutdown (void)
285{
286 if (NULL != dht_handle)
287 {
288 GNUNET_DHT_disconnect (dht_handle);
289 dht_handle = NULL;
290 }
291 if (NULL != announce_id_task)
292 {
293 GNUNET_SCHEDULER_cancel (announce_id_task);
294 announce_id_task = NULL;
295 }
296}
297
298
299/**
300 * Search DHT for paths to @a peeR_id
301 *
302 * @param peer_id peer to search for
303 * @return handle to abort search
304 */
305struct GCD_search_handle *
306GCD_search (const struct GNUNET_PeerIdentity *peer_id)
307{
308 struct GNUNET_HashCode phash;
309 struct GCD_search_handle *h;
310
311 GNUNET_STATISTICS_update (stats,
312 "# DHT search",
313 1,
314 GNUNET_NO);
315 memset (&phash,
316 0,
317 sizeof(phash));
318 GNUNET_memcpy (&phash,
319 peer_id,
320 sizeof(*peer_id));
321
322 h = GNUNET_new (struct GCD_search_handle);
323 h->dhtget = GNUNET_DHT_get_start (dht_handle, /* handle */
324 GNUNET_BLOCK_TYPE_DHT_HELLO, /* type */
325 &phash, /* key to search */
326 dht_replication_level, /* replication level */
327 GNUNET_DHT_RO_RECORD_ROUTE
328 | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
329 NULL, /* xquery */
330 0, /* xquery bits */
331 &dht_get_id_handler,
332 h);
333 LOG (GNUNET_ERROR_TYPE_DEBUG,
334 "Starting DHT GET for peer %s (%p)\n",
335 GNUNET_i2s (peer_id),
336 h);
337 return h;
338}
339
340
341/**
342 * Stop DHT search started with #GCD_search().
343 *
344 * @param h handle to search to stop
345 */
346void
347GCD_search_stop (struct GCD_search_handle *h)
348{
349 LOG (GNUNET_ERROR_TYPE_DEBUG,
350 "Stopping DHT GET %p\n",
351 h);
352 GNUNET_DHT_get_stop (h->dhtget);
353 GNUNET_free (h);
354}
355
356
357/* end of gnunet-service-cadet_dht.c */