GNUnet 0.22.1
gnunet-service-dht.c
Go to the documentation of this file.
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
27#include "platform.h"
28#include "gnunet_common.h"
29#include "gnunet_block_lib.h"
30#include "gnunet_util_lib.h"
33#include "gnunet-service-dht.h"
37#include "plugin_dhtu_ip.h"
38#include "plugin_dhtu_gnunet.h"
39
44#define HELLO_FREQUENCY GNUNET_TIME_UNIT_HOURS
45
46
51{
52
57
62
67
72
77
81 char *name;
82};
83
84
89{
93 struct MyAddress *next;
94
98 struct MyAddress *prev;
99
104
108 char *url;
109
114};
115
116
121
126
131
136
141
145static struct GDS_Underlay *u_head;
146
150static struct GDS_Underlay *u_tail;
151
155static struct MyAddress *a_head;
156
160static struct MyAddress *a_tail;
161
167
168
178static void
181 double logestimate,
182 double std_dev)
183{
184 struct GDS_Underlay *u = cls;
185 double sum = 0.0;
186
188 "# Network size estimates received",
189 1,
190 GNUNET_NO);
191 /* do not allow estimates < 0.5 */
192 u->network_size_estimate = pow (2.0,
193 GNUNET_MAX (0.5,
194 logestimate));
195 for (struct GDS_Underlay *p = u_head; NULL != p; p = p->next)
196 sum += p->network_size_estimate;
197 if (sum <= 2.0)
199 else
201}
202
203
209double
211{
213}
214
215
217
218
224static void
226{
227 struct GNUNET_MessageHeader *hello;
228
229 (void) cls;
230 /* TODO: randomize! */
233 NULL);
237 if (NULL == hello)
238 {
239 GNUNET_break (0);
240 return;
241 }
243 GNUNET_free (hello);
244}
245
246
256static void
257u_address_add (void *cls,
258 const char *address,
260 void **ctx)
261{
262 struct GDS_Underlay *u = cls;
263 struct MyAddress *a;
264 enum GNUNET_GenericReturnValue add_success;
265
267 "Underlay adds address %s for this peer\n",
268 address);
269 if (GNUNET_OK != (add_success = GNUNET_HELLO_builder_add_address (
271 address)))
272 {
274 "Adding address `%s' from underlay %s\n",
275 address,
276 GNUNET_NO == add_success ? "not done" : "failed");
277 return;
278 }
279 a = GNUNET_new (struct MyAddress);
280 a->source = source;
282 a->u = u;
284 a_tail,
285 a);
286 *ctx = a;
287
288 if (NULL != hello_task)
291 NULL);
292}
293
294
300static void
302{
303 struct MyAddress *a = ctx;
304
306 "Underlay deletes address %s for this peer\n",
307 a->url);
309 a->url);
311 a_tail,
312 a);
313 GNUNET_free (a->url);
314 GNUNET_free (a);
315 if (NULL != hello_task)
318 NULL);
319}
320
321
322void
324 const char *address)
325{
326 for (struct GDS_Underlay *u = u_head;
327 NULL != u;
328 u = u->next)
329 u->dhtu->try_connect (u->dhtu->cls,
330 pid,
331 address);
332}
333
334
335void
337 struct GNUNET_DHTU_Target *target,
338 const void *msg,
339 size_t msg_size,
341 void *finished_cb_cls)
342{
343 u->dhtu->send (u->dhtu->cls,
344 target,
345 msg,
346 msg_size,
348 finished_cb_cls);
349}
350
351
352void
355{
356 u->dhtu->drop (ph);
357}
358
359
363{
364 return u->dhtu->hold (u->dhtu->cls,
365 target);
366}
367
368
374static void
375shutdown_task (void *cls)
376{
377 struct GDS_Underlay *u;
378
379 while (NULL != (u = u_head))
380 {
382 u_tail,
383 u);
384 if (0 == strcmp (u->name, "gnunet"))
385 {
386 DHTU_gnunet_done (u->dhtu);
387 }
388 else if (0 == strcmp (u->name, "ip"))
389 {
390 DHTU_ip_done (u->dhtu);
391 }
392 else
393 {
394 GNUNET_assert (0);
395 }
396 GNUNET_free (u->name);
397 GNUNET_free (u);
398 }
402 if (NULL != GDS_block_context)
403 {
405 GDS_block_context = NULL;
406 }
408 if (NULL != GDS_stats)
409 {
411 GNUNET_YES);
412 GDS_stats = NULL;
413 }
414 if (NULL != GDS_my_hello)
415 {
417 GDS_my_hello = NULL;
418 }
419 if (NULL != hello_task)
420 {
422 hello_task = NULL;
423 }
424}
425
426
434static void
435load_underlay (void *cls,
436 const char *section)
437{
438 struct GDS_Underlay *u;
439
440 (void) cls;
441 if (0 != strncasecmp (section,
442 "dhtu-",
443 strlen ("dhtu-")))
444 return;
445 if (GNUNET_YES !=
447 section,
448 "ENABLED"))
449 return;
450 section += strlen ("dhtu-");
451 u = GNUNET_new (struct GDS_Underlay);
452 u->env.cls = u;
453 u->env.cfg = GDS_cfg;
454 u->env.address_add_cb = &u_address_add;
455 u->env.address_del_cb = &u_address_del;
456 u->env.network_size_cb = &update_network_size_estimate;
457 u->env.connect_cb = &GDS_u_connect;
458 u->env.disconnect_cb = &GDS_u_disconnect;
459 u->env.receive_cb = &GDS_u_receive;
460
463 if (0 == strcmp (section, "gnunet"))
464 {
465 u->dhtu = DHTU_gnunet_init (&u->env);
466 }
467 else if (0 == strcmp (section, "ip"))
468 {
469 u->dhtu = DHTU_ip_init (&u->env);
470 }
471 if (NULL == u->dhtu)
472 {
473 GNUNET_free (u);
474 return;
475 }
476 u->name = GNUNET_strdup (section);
478 u_tail,
479 u);
480}
481
482
490static void
491run (void *cls,
492 const struct GNUNET_CONFIGURATION_Handle *c,
494{
495 GDS_cfg = c;
497 {
498 char *keyfile;
499
500 if (GNUNET_OK !=
502 "PEER",
503 "PRIVATE_KEY",
504 &keyfile))
505 {
507 "PEER",
508 "PRIVATE_KEY");
510 return;
511 }
512 if (GNUNET_SYSERR ==
516 {
518 "Failed to setup peer's private key\n");
519 GNUNET_free (keyfile);
521 return;
522 }
523 GNUNET_free (keyfile);
524 }
529 sizeof(struct GNUNET_PeerIdentity),
533 GDS_cfg);
538 NULL);
539 if (GNUNET_OK !=
541 {
543 return;
544 }
547 NULL);
548 if (NULL == u_head)
549 {
551 "No DHT underlays configured!\n");
553 return;
554 }
555}
556
557
558/* Finally, define the main method */
560
561
562/* end of gnunet-service-dht.c */
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static mp_limb_t u[(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
static void finished_cb(void *cls, enum GNUNET_GenericReturnValue rv)
static uint64_t timestamp(void)
Get current timestamp.
static char * address
GNS address for this phone.
static struct GNUNET_FS_Handle * ctx
static GstElement * source
Appsrc instance into which we write data for the pipeline.
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
static void load_underlay(void *cls, const char *section)
Function iterating over all configuration sections.
struct GNUNET_PeerIdentity GDS_my_identity
Identity of this peer.
double GDS_NSE_get(void)
Return the current NSE.
static struct MyAddress * a_head
Head of addresses of this peer.
static void u_address_add(void *cls, const char *address, struct GNUNET_DHTU_Source *source, void **ctx)
Function to call with new addresses of this peer.
static struct MyAddress * a_tail
Tail of addresses of this peer.
struct GNUNET_CRYPTO_EddsaPrivateKey GDS_my_private_key
Our private key.
static struct GDS_Underlay * u_head
Handles for the DHT underlays.
static void shutdown_task(void *cls)
Task run during shutdown.
static void u_address_del(void *ctx)
Function to call with expired addresses of this peer.
struct GNUNET_DHTU_PreferenceHandle * GDS_u_hold(struct GDS_Underlay *u, struct GNUNET_DHTU_Target *target)
Create a hold on target at underlay u.
void GDS_u_send(struct GDS_Underlay *u, struct GNUNET_DHTU_Target *target, const void *msg, size_t msg_size, GNUNET_SCHEDULER_TaskCallback finished_cb, void *finished_cb_cls)
Send message to some other participant over the network.
static struct GDS_Underlay * u_tail
Handles for the DHT underlays.
#define HELLO_FREQUENCY
How often do we broadcast our HELLO to neighbours if nothing special happens?
static struct GNUNET_SCHEDULER_Task * hello_task
Task broadcasting our HELLO.
static void run(void *cls, const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_SERVICE_Handle *service)
Process dht requests.
struct GNUNET_HELLO_Builder * GDS_my_hello
Our HELLO.
void GDS_u_drop(struct GDS_Underlay *u, struct GNUNET_DHTU_PreferenceHandle *ph)
Drop a hold ph from underlay u.
void GDS_u_try_connect(const struct GNUNET_PeerIdentity *pid, const char *address)
Ask all underlays to connect to peer pid at address.
struct GNUNET_HashCode GDS_my_identity_hash
Hash of the identity of this peer.
static void broadcast_hello(void *cls)
Task run periodically to broadcast our HELLO.
static double log_of_network_size_estimate
log of the current network size estimate, used as the point where we switch between random and determ...
static void update_network_size_estimate(void *cls, struct GNUNET_TIME_Absolute timestamp, double logestimate, double std_dev)
Callback that is called when network size estimate is updated.
GNUnet DHT globals.
struct GNUNET_STATISTICS_Handle * GDS_stats
Handle for the statistics service.
struct GNUNET_BLOCK_Context * GDS_block_context
Our handle to the BLOCK library.
struct GNUNET_SERVICE_Handle * GDS_service
Handle for the service.
const struct GNUNET_CONFIGURATION_Handle * GDS_cfg
Configuration we use.
GNUnet DHT service's client management code.
#define GDS_DHT_SERVICE_INIT(name, run)
Define "main" method using service macro.
void GDS_CLIENTS_init(void)
Initialize client subsystem.
void GDS_CLIENTS_stop(void)
Shutdown client subsystem.
void GDS_DATACACHE_init()
Initialize datacache subsystem.
void GDS_DATACACHE_done()
Shutdown datacache subsystem.
GNUnet DHT service's datacache integration.
void GDS_NEIGHBOURS_done()
Shutdown neighbours subsystem.
void GDS_u_disconnect(void *ctx)
Function to call when we disconnected from a peer and can henceforth cannot transmit to that peer any...
void GDS_NEIGHBOURS_broadcast(const struct GNUNET_MessageHeader *msg)
Send msg to all peers in our buckets.
void GDS_u_connect(void *cls, struct GNUNET_DHTU_Target *target, const struct GNUNET_PeerIdentity *pid, void **ctx)
Function to call when we connect to a peer and can henceforth transmit to that peer.
enum GNUNET_GenericReturnValue GDS_NEIGHBOURS_init()
Initialize neighbours subsystem.
void GDS_u_receive(void *cls, void **tctx, void **sctx, const void *message, size_t message_size)
Function to call when we receive a message.
GNUnet DHT routing code.
void GDS_ROUTING_done()
Shutdown routing subsystem.
void GDS_ROUTING_init()
Initialize routing subsystem.
GNUnet DHT tracking of requests for routing replies.
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-uri.c:38
Library for data block manipulation.
commonly used definitions; globals in this file are exempt from the rule that the module name ("commo...
Helper library for handling HELLO URIs.
API to create, modify and access statistics.
void GNUNET_BLOCK_context_destroy(struct GNUNET_BLOCK_Context *ctx)
Destroy the block context.
Definition: block.c:156
struct GNUNET_BLOCK_Context * GNUNET_BLOCK_context_create(const struct GNUNET_CONFIGURATION_Handle *cfg)
Create a block context.
Definition: block.c:140
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
void GNUNET_CONFIGURATION_iterate_sections(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_CONFIGURATION_SectionIterator iter, void *iter_cls)
Iterate over all sections in the configuration.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_key_from_file(const char *filename, int do_create, struct GNUNET_CRYPTO_EddsaPrivateKey *pkey)
Create a new private key by reading it from a file.
void GNUNET_CRYPTO_eddsa_key_get_public(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:201
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
void GNUNET_HELLO_builder_free(struct GNUNET_HELLO_Builder *builder)
Release resources of a builder.
Definition: hello-uri.c:453
struct GNUNET_HELLO_Builder * GNUNET_HELLO_builder_new(const struct GNUNET_PeerIdentity *pid)
Allocate builder.
Definition: hello-uri.c:401
enum GNUNET_GenericReturnValue GNUNET_HELLO_builder_del_address(struct GNUNET_HELLO_Builder *builder, const char *address)
Remove individual address from the builder.
Definition: hello-uri.c:1177
enum GNUNET_GenericReturnValue GNUNET_HELLO_builder_add_address(struct GNUNET_HELLO_Builder *builder, const char *address)
Add individual address to the builder.
Definition: hello-uri.c:646
struct GNUNET_MessageHeader * GNUNET_HELLO_builder_to_dht_hello_msg(const struct GNUNET_HELLO_Builder *builder, const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, struct GNUNET_TIME_Relative expiration_time)
Generate DHT HELLO message (without peer ID) from a builder.
Definition: hello-uri.c:822
#define GNUNET_log(kind,...)
#define GNUNET_MAX(a, b)
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_INFO
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:566
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition: scheduler.c:1338
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:979
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1303
void(* GNUNET_SCHEDULER_TaskCallback)(void *cls)
Signature of the main function of a task.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1276
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
#define GNUNET_TIME_UNIT_ZERO
Relative time zero.
void * DHTU_gnunet_done(struct GNUNET_DHTU_PluginFunctions *api)
Exit point from the plugin.
struct GNUNET_DHTU_PluginFunctions * DHTU_gnunet_init(struct GNUNET_DHTU_PluginEnvironment *env)
Entry point for the plugin.
struct GNUNET_DHTU_PluginFunctions * DHTU_ip_init(struct GNUNET_DHTU_PluginEnvironment *env)
Entry point for the plugin.
void * DHTU_ip_done(struct GNUNET_DHTU_PluginFunctions *api)
Exit point from the plugin.
Information we keep per underlay.
struct GNUNET_DHTU_PluginEnvironment env
Environment for this underlay.
struct GDS_Underlay * prev
Kept in a DLL.
double network_size_estimate
current network size estimate for this underlay.
char * name
Name of the underlay (i.e.
struct GDS_Underlay * next
Kept in a DLL.
struct GNUNET_DHTU_PluginFunctions * dhtu
Underlay API handle.
Private ECC key encoded for transmission.
The datastore service will pass a pointer to a struct of this type as the first and only argument to ...
struct returned by the initialization function of the plugin
Opaque handle expressing a preference of the DHT to keep a particular target connected.
struct GNUNET_DHTU_Target * target
Target a preference was expressed for.
Opaque handle that the underlay offers for our address to be used when sending messages to another pe...
Opaque handle that the underlay offers for the target peer when sending messages to another peer.
Context for building (or parsing) HELLO URIs.
Definition: hello-uri.c:205
A 512-bit hashcode.
Header for all communications.
The identity of the host (wraps the signing key of the peer).
struct GNUNET_CRYPTO_EddsaPublicKey public_key
Entry in list of pending tasks.
Definition: scheduler.c:135
Handle to a service.
Definition: service.c:116
Time for absolute times used by GNUnet, in microseconds.
An address of this peer.
char * url
Textual representation of the address.
struct GDS_Underlay * u
Underlay of this address.
struct MyAddress * prev
Kept in a DLL.
struct MyAddress * next
Kept in a DLL.
struct GNUNET_DHTU_Source * source
Underlay handle for the address.