aboutsummaryrefslogtreecommitdiff
path: root/src/dht/gnunet-service-dht.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dht/gnunet-service-dht.c')
-rw-r--r--src/dht/gnunet-service-dht.c543
1 files changed, 0 insertions, 543 deletions
diff --git a/src/dht/gnunet-service-dht.c b/src/dht/gnunet-service-dht.c
deleted file mode 100644
index 39433791d..000000000
--- a/src/dht/gnunet-service-dht.c
+++ /dev/null
@@ -1,543 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009, 2010, 2011, 2016 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/**
22 * @file dht/gnunet-service-dht.c
23 * @brief GNUnet DHT service
24 * @author Christian Grothoff
25 * @author Nathan Evans
26 */
27#include "platform.h"
28#include "gnunet_block_lib.h"
29#include "gnunet_util_lib.h"
30#include "gnunet_hello_lib.h"
31#include "gnunet_hello_uri_lib.h"
32#include "gnunet_dht_service.h"
33#include "gnunet_statistics_service.h"
34#include "gnunet-service-dht.h"
35#include "gnunet-service-dht_datacache.h"
36#include "gnunet-service-dht_neighbours.h"
37#include "gnunet-service-dht_routing.h"
38
39/**
40 * How often do we broadcast our HELLO to neighbours if
41 * nothing special happens?
42 */
43#define HELLO_FREQUENCY GNUNET_TIME_UNIT_HOURS
44
45
46/**
47 * Information we keep per underlay.
48 */
49struct GDS_Underlay
50{
51
52 /**
53 * Kept in a DLL.
54 */
55 struct GDS_Underlay *next;
56
57 /**
58 * Kept in a DLL.
59 */
60 struct GDS_Underlay *prev;
61
62 /**
63 * Environment for this underlay.
64 */
65 struct GNUNET_DHTU_PluginEnvironment env;
66
67 /**
68 * Underlay API handle.
69 */
70 struct GNUNET_DHTU_PluginFunctions *dhtu;
71
72 /**
73 * current network size estimate for this underlay.
74 */
75 double network_size_estimate;
76
77 /**
78 * Name of the underlay (i.e. "gnunet" or "ip").
79 */
80 char *name;
81
82 /**
83 * Name of the library providing the underlay.
84 */
85 char *libname;
86};
87
88
89/**
90 * An address of this peer.
91 */
92struct MyAddress
93{
94 /**
95 * Kept in a DLL.
96 */
97 struct MyAddress *next;
98
99 /**
100 * Kept in a DLL.
101 */
102 struct MyAddress *prev;
103
104 /**
105 * Underlay handle for the address.
106 */
107 struct GNUNET_DHTU_Source *source;
108
109 /**
110 * Textual representation of the address.
111 */
112 char *url;
113
114 /**
115 * Underlay of this address.
116 */
117 struct GDS_Underlay *u;
118};
119
120
121/**
122 * Our HELLO
123 */
124struct GNUNET_HELLO_Builder *GDS_my_hello;
125
126/**
127 * Identity of this peer.
128 */
129struct GNUNET_PeerIdentity GDS_my_identity;
130
131/**
132 * Hash of the identity of this peer.
133 */
134struct GNUNET_HashCode GDS_my_identity_hash;
135
136/**
137 * Our private key.
138 */
139struct GNUNET_CRYPTO_EddsaPrivateKey GDS_my_private_key;
140
141/**
142 * Task broadcasting our HELLO.
143 */
144static struct GNUNET_SCHEDULER_Task *hello_task;
145
146/**
147 * Handles for the DHT underlays.
148 */
149static struct GDS_Underlay *u_head;
150
151/**
152 * Handles for the DHT underlays.
153 */
154static struct GDS_Underlay *u_tail;
155
156/**
157 * Head of addresses of this peer.
158 */
159static struct MyAddress *a_head;
160
161/**
162 * Tail of addresses of this peer.
163 */
164static struct MyAddress *a_tail;
165
166/**
167 * log of the current network size estimate, used as the point where
168 * we switch between random and deterministic routing.
169 */
170static double log_of_network_size_estimate;
171
172
173/**
174 * Callback that is called when network size estimate is updated.
175 *
176 * @param cls a `struct GDS_Underlay`
177 * @param timestamp time when the estimate was received from the server (or created by the server)
178 * @param logestimate the log(Base 2) value of the current network size estimate
179 * @param std_dev standard deviation for the estimate
180 *
181 */
182static void
183update_network_size_estimate (void *cls,
184 struct GNUNET_TIME_Absolute timestamp,
185 double logestimate,
186 double std_dev)
187{
188 struct GDS_Underlay *u = cls;
189 double sum = 0.0;
190
191 GNUNET_STATISTICS_update (GDS_stats,
192 "# Network size estimates received",
193 1,
194 GNUNET_NO);
195 /* do not allow estimates < 0.5 */
196 u->network_size_estimate = pow (2.0,
197 GNUNET_MAX (0.5,
198 logestimate));
199 for (struct GDS_Underlay *p = u_head; NULL != p; p = p->next)
200 sum += p->network_size_estimate;
201 if (sum <= 2.0)
202 log_of_network_size_estimate = 0.5;
203 else
204 log_of_network_size_estimate = log2 (sum);
205}
206
207
208/**
209 * Return the current NSE
210 *
211 * @return the current NSE as a logarithm
212 */
213double
214GDS_NSE_get (void)
215{
216 return log_of_network_size_estimate;
217}
218
219
220#include "gnunet-service-dht_clients.c"
221
222
223/**
224 * Task run periodically to broadcast our HELLO.
225 *
226 * @param cls NULL
227 */
228static void
229broadcast_hello (void *cls)
230{
231 struct GNUNET_MessageHeader *hello;
232
233 (void) cls;
234 /* TODO: randomize! */
235 hello_task = GNUNET_SCHEDULER_add_delayed (HELLO_FREQUENCY,
236 &broadcast_hello,
237 NULL);
238 hello = GNUNET_HELLO_builder_to_dht_hello_msg (GDS_my_hello,
239 &GDS_my_private_key);
240 if (NULL == hello)
241 {
242 GNUNET_break (0);
243 return;
244 }
245 GDS_NEIGHBOURS_broadcast (hello);
246 GNUNET_free (hello);
247}
248
249
250/**
251 * Function to call with new addresses of this peer.
252 *
253 * @param cls the closure
254 * @param address address under which we are likely reachable,
255 * pointer will remain valid until @e address_del_cb is called; to be used for HELLOs. Example: "ip+udp://$PID/1.1.1.1:2086/"
256 * @param source handle for sending from this address, NULL if we can only receive
257 * @param[out] ctx storage space for DHT to use in association with this address
258 */
259static void
260u_address_add (void *cls,
261 const char *address,
262 struct GNUNET_DHTU_Source *source,
263 void **ctx)
264{
265 struct GDS_Underlay *u = cls;
266 struct MyAddress *a;
267
268 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
269 "Underlay adds address %s for this peer\n",
270 address);
271 a = GNUNET_new (struct MyAddress);
272 a->source = source;
273 a->url = GNUNET_strdup (address);
274 a->u = u;
275 GNUNET_CONTAINER_DLL_insert (a_head,
276 a_tail,
277 a);
278 *ctx = a;
279 GNUNET_HELLO_builder_add_address (GDS_my_hello,
280 address);
281 if (NULL != hello_task)
282 GNUNET_SCHEDULER_cancel (hello_task);
283 hello_task = GNUNET_SCHEDULER_add_now (&broadcast_hello,
284 NULL);
285}
286
287
288/**
289 * Function to call with expired addresses of this peer.
290 *
291 * @param[in] ctx storage space used by the DHT in association with this address
292 */
293static void
294u_address_del (void *ctx)
295{
296 struct MyAddress *a = ctx;
297
298 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
299 "Underlay deletes address %s for this peer\n",
300 a->url);
301 GNUNET_HELLO_builder_del_address (GDS_my_hello,
302 a->url);
303 GNUNET_CONTAINER_DLL_remove (a_head,
304 a_tail,
305 a);
306 GNUNET_free (a->url);
307 GNUNET_free (a);
308 if (NULL != hello_task)
309 GNUNET_SCHEDULER_cancel (hello_task);
310 hello_task = GNUNET_SCHEDULER_add_now (&broadcast_hello,
311 NULL);
312}
313
314
315void
316GDS_u_try_connect (const struct GNUNET_PeerIdentity *pid,
317 const char *address)
318{
319 for (struct GDS_Underlay *u = u_head;
320 NULL != u;
321 u = u->next)
322 u->dhtu->try_connect (u->dhtu->cls,
323 pid,
324 address);
325}
326
327
328void
329GDS_u_send (struct GDS_Underlay *u,
330 struct GNUNET_DHTU_Target *target,
331 const void *msg,
332 size_t msg_size,
333 GNUNET_SCHEDULER_TaskCallback finished_cb,
334 void *finished_cb_cls)
335{
336 u->dhtu->send (u->dhtu->cls,
337 target,
338 msg,
339 msg_size,
340 finished_cb,
341 finished_cb_cls);
342}
343
344
345void
346GDS_u_drop (struct GDS_Underlay *u,
347 struct GNUNET_DHTU_PreferenceHandle *ph)
348{
349 u->dhtu->drop (ph);
350}
351
352
353struct GNUNET_DHTU_PreferenceHandle *
354GDS_u_hold (struct GDS_Underlay *u,
355 struct GNUNET_DHTU_Target *target)
356{
357 return u->dhtu->hold (u->dhtu->cls,
358 target);
359}
360
361
362/**
363 * Task run during shutdown.
364 *
365 * @param cls unused
366 */
367static void
368shutdown_task (void *cls)
369{
370 struct GDS_Underlay *u;
371
372 while (NULL != (u = u_head))
373 {
374 GNUNET_PLUGIN_unload (u->libname,
375 u->dhtu);
376 GNUNET_CONTAINER_DLL_remove (u_head,
377 u_tail,
378 u);
379 GNUNET_free (u->name);
380 GNUNET_free (u->libname);
381 GNUNET_free (u);
382 }
383 GDS_NEIGHBOURS_done ();
384 GDS_DATACACHE_done ();
385 GDS_ROUTING_done ();
386 if (NULL != GDS_block_context)
387 {
388 GNUNET_BLOCK_context_destroy (GDS_block_context);
389 GDS_block_context = NULL;
390 }
391 GDS_CLIENTS_stop ();
392 if (NULL != GDS_stats)
393 {
394 GNUNET_STATISTICS_destroy (GDS_stats,
395 GNUNET_YES);
396 GDS_stats = NULL;
397 }
398 if (NULL != GDS_my_hello)
399 {
400 GNUNET_HELLO_builder_free (GDS_my_hello);
401 GDS_my_hello = NULL;
402 }
403 if (NULL != hello_task)
404 {
405 GNUNET_SCHEDULER_cancel (hello_task);
406 hello_task = NULL;
407 }
408}
409
410
411/**
412 * Function iterating over all configuration sections.
413 * Loads plugins for enabled DHT underlays.
414 *
415 * @param cls NULL
416 * @param section configuration section to inspect
417 */
418static void
419load_underlay (void *cls,
420 const char *section)
421{
422 struct GDS_Underlay *u;
423 char *libname;
424
425 (void) cls;
426 if (0 != strncasecmp (section,
427 "dhtu-",
428 strlen ("dhtu-")))
429 return;
430 if (GNUNET_YES !=
431 GNUNET_CONFIGURATION_get_value_yesno (GDS_cfg,
432 section,
433 "ENABLED"))
434 return;
435 section += strlen ("dhtu-");
436 u = GNUNET_new (struct GDS_Underlay);
437 u->env.cls = u;
438 u->env.cfg = GDS_cfg;
439 u->env.address_add_cb = &u_address_add;
440 u->env.address_del_cb = &u_address_del;
441 u->env.network_size_cb = &update_network_size_estimate;
442 u->env.connect_cb = &GDS_u_connect;
443 u->env.disconnect_cb = &GDS_u_disconnect;
444 u->env.receive_cb = &GDS_u_receive;
445 GNUNET_asprintf (&libname,
446 "libgnunet_plugin_dhtu_%s",
447 section);
448 u->dhtu = GNUNET_PLUGIN_load (libname,
449 &u->env);
450 if (NULL == u->dhtu)
451 {
452 GNUNET_free (libname);
453 GNUNET_free (u);
454 return;
455 }
456 u->libname = libname;
457 u->name = GNUNET_strdup (section);
458 GNUNET_CONTAINER_DLL_insert (u_head,
459 u_tail,
460 u);
461}
462
463
464/**
465 * Process dht requests.
466 *
467 * @param cls closure
468 * @param c configuration to use
469 * @param service the initialized service
470 */
471static void
472run (void *cls,
473 const struct GNUNET_CONFIGURATION_Handle *c,
474 struct GNUNET_SERVICE_Handle *service)
475{
476 GDS_cfg = c;
477 GDS_service = service;
478 {
479 char *keyfile;
480
481 if (GNUNET_OK !=
482 GNUNET_CONFIGURATION_get_value_filename (GDS_cfg,
483 "PEER",
484 "PRIVATE_KEY",
485 &keyfile))
486 {
487 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
488 "PEER",
489 "PRIVATE_KEY");
490 GNUNET_SCHEDULER_shutdown ();
491 return;
492 }
493 if (GNUNET_SYSERR ==
494 GNUNET_CRYPTO_eddsa_key_from_file (keyfile,
495 GNUNET_YES,
496 &GDS_my_private_key))
497 {
498 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
499 "Failed to setup peer's private key\n");
500 GNUNET_free (keyfile);
501 GNUNET_SCHEDULER_shutdown ();
502 return;
503 }
504 GNUNET_free (keyfile);
505 }
506 GNUNET_CRYPTO_eddsa_key_get_public (&GDS_my_private_key,
507 &GDS_my_identity.public_key);
508 GDS_my_hello = GNUNET_HELLO_builder_new (&GDS_my_identity);
509 GNUNET_CRYPTO_hash (&GDS_my_identity,
510 sizeof(struct GNUNET_PeerIdentity),
511 &GDS_my_identity_hash);
512 GDS_block_context = GNUNET_BLOCK_context_create (GDS_cfg);
513 GDS_stats = GNUNET_STATISTICS_create ("dht",
514 GDS_cfg);
515 GDS_CLIENTS_init ();
516 GDS_ROUTING_init ();
517 GDS_DATACACHE_init ();
518 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
519 NULL);
520 if (GNUNET_OK !=
521 GDS_NEIGHBOURS_init ())
522 {
523 GNUNET_SCHEDULER_shutdown ();
524 return;
525 }
526 GNUNET_CONFIGURATION_iterate_sections (GDS_cfg,
527 &load_underlay,
528 NULL);
529 if (NULL == u_head)
530 {
531 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
532 "No DHT underlays configured!\n");
533 GNUNET_SCHEDULER_shutdown ();
534 return;
535 }
536}
537
538
539/* Finally, define the main method */
540GDS_DHT_SERVICE_INIT ("dht", &run);
541
542
543/* end of gnunet-service-dht.c */