GNUnet 0.28.1-dev.4-8-g14b9efcb0
 
Loading...
Searching...
No Matches
gnunet-service-dht.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009-2011, 2016, 2026 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"
32#include "gnunet_pils_service.h"
34#include "gnunet-service-dht.h"
38#include "plugin_dhtu_ip.h"
39#include "plugin_dhtu_gnunet.h"
40#include "dht_helper.h"
41
46#define HELLO_FREQUENCY GNUNET_TIME_UNIT_HOURS
47
48
85
86
91{
95 struct MyAddress *next;
96
101
106
110 char *url;
111
116};
117
121struct PilsRequest
122{
126 struct PilsRequest *prev;
127
131 struct PilsRequest *next;
132
137};
138
143
148
149
154
158static struct GDS_Underlay *u_head;
159
163static struct GDS_Underlay *u_tail;
164
168static struct MyAddress *a_head;
169
173static struct MyAddress *a_tail;
174
180
185static bool serving_clients;
186
187
197static void
200 double logestimate,
201 double std_dev)
202{
203 struct GDS_Underlay *u = cls;
204 double sum = 0.0;
205
207 "# Network size estimates received",
208 1,
209 GNUNET_NO);
210 /* do not allow estimates < #MINIMUM_LOG_NSE */
211 u->network_size_estimate = pow (2.0,
213 logestimate));
214 for (struct GDS_Underlay *p = u_head; NULL != p; p = p->next)
215 sum += p->network_size_estimate;
216 if (sum <= 2.0)
218 else
219 log_of_network_size_estimate = log2 (sum);
220}
221
222
228double
230{
232}
233
234
236
237
247static void
248u_address_add (void *cls,
249 const char *address,
251 void **ctx)
252{
253 struct GDS_Underlay *u = cls;
254 struct MyAddress *a;
255
257 "Underlay adds address %s for this peer\n",
258 address);
259 a = GNUNET_new (struct MyAddress);
260 a->source = source;
262 a->u = u;
264 a_tail,
265 a);
266 *ctx = a;
267
268}
269
270
276static void
278{
279 struct MyAddress *a = ctx;
280
282 "Underlay deletes address %s for this peer\n",
283 a->url);
285 a_tail,
286 a);
287 GNUNET_free (a->url);
288 GNUNET_free (a);
289}
290
291
292void
294 const char *address)
295{
296 for (struct GDS_Underlay *u = u_head;
297 NULL != u;
298 u = u->next)
299 u->dhtu->try_connect (u->dhtu->cls,
300 pid,
301 address);
302}
303
304
305void
307 struct GNUNET_DHTU_Target *target,
308 const void *msg,
309 size_t msg_size,
311 void *finished_cb_cls)
312{
313 u->dhtu->send (u->dhtu->cls,
314 target,
315 msg,
316 msg_size,
318 finished_cb_cls);
319}
320
321
322void
325{
326 u->dhtu->drop (ph);
327}
328
329
333{
334 return u->dhtu->hold (u->dhtu->cls,
335 target);
336}
337
338
344static void
345shutdown_task (void *cls)
346{
347 struct GDS_Underlay *u;
348 struct PilsRequest *pr;
349
350 while (NULL != (u = u_head))
351 {
353 u_tail,
354 u);
355 if (0 == strcmp (u->name, "gnunet"))
356 {
357 DHTU_gnunet_done (u->dhtu);
358 }
359#ifdef LINUX
360 else if (0 == strcmp (u->name, "ip"))
361 {
362 DHTU_ip_done (u->dhtu);
363 }
364#endif
365 else
366 {
367 GNUNET_assert (0);
368 }
369 GNUNET_free (u->name);
370 GNUNET_free (u);
371 }
375 if (NULL != GDS_block_context)
376 {
378 GDS_block_context = NULL;
379 }
381 if (NULL != GDS_stats)
382 {
384 GNUNET_YES);
385 GDS_stats = NULL;
386 }
387 if (NULL != GDS_my_hello)
388 {
390 GDS_my_hello = NULL;
391 }
392 while (NULL != (pr = pils_requests_head))
393 {
396 pr);
397 if (NULL != pr->op)
399 GNUNET_free (pr);
400 }
402 if (NULL != GDS_pils)
403 {
405 GDS_pils = NULL;
406 }
407}
408
409
417static void
418load_underlay (void *cls,
419 const char *section)
420{
421 struct GDS_Underlay *u;
422
423 (void) cls;
424 if (0 != strncasecmp (section,
425 "dhtu-",
426 strlen ("dhtu-")))
427 return;
428 if (GNUNET_YES !=
430 section,
431 "ENABLED"))
432 return;
433 section += strlen ("dhtu-");
434 u = GNUNET_new (struct GDS_Underlay);
435 u->env.cls = u;
436 u->env.cfg = GDS_cfg;
437 u->env.address_add_cb = &u_address_add;
438 u->env.address_del_cb = &u_address_del;
439 u->env.network_size_cb = &update_network_size_estimate;
440 u->env.connect_cb = &GDS_u_connect;
441 u->env.disconnect_cb = &GDS_u_disconnect;
442 u->env.receive_cb = &GDS_u_receive;
443
446 if (0 == strcmp (section, "gnunet"))
447 {
448 u->dhtu = DHTU_gnunet_init (&u->env);
449 }
450#ifdef LINUX
451 else if (0 == strcmp (section, "ip"))
452 {
453 u->dhtu = DHTU_ip_init (&u->env);
454 }
455#endif
456 if (NULL == u->dhtu)
457 {
458 GNUNET_free (u);
459 return;
460 }
461 u->name = GNUNET_strdup (section);
463 u_tail,
464 u);
465}
466
467
468static void
469pid_change_cb (void *cls,
470 const struct GNUNET_HELLO_Parser *parser,
471 const struct GNUNET_HashCode *hash)
472{
473 (void) cls;
474
475 if (NULL != GDS_my_hello)
478
479 if (NULL == GDS_my_hello)
480 {
481 GNUNET_break (0);
482 return;
483 }
484
485 if (NULL == u_head)
486 {
489 NULL);
490 if (NULL == u_head)
491 {
493 "No DHT underlays configured!\n");
495 return;
496 }
497 }
498
499 if (! serving_clients)
500 {
501 /* We have an identity now, so we can answer clients. */
502 serving_clients = true;
505 _ ("DHT service of `%s' ready.\n"),
507 }
508
510}
511
512
520static void
521run (void *cls,
522 const struct GNUNET_CONFIGURATION_Handle *c,
524{
525 GDS_cfg = c;
527 /* Do not accept clients until PILS gave us our peer identity: without
528 it we can neither store nor route anything (#GDS_am_closest_peer(),
529 #GDS_DATACACHE_handle_put() and #GDS_NEIGHBOURS_handle_put() all
530 need it). #pid_change_cb() resumes us. */
533 GNUNET_assert (NULL != GDS_pils);
534 /* Sign path elements ourselves instead of asking the PILS service:
535 the signature is needed in the middle of building a message, and
536 the asynchronous round-trip forces every caller to keep the
537 half-built message alive across the callback. */
538 if (GNUNET_OK !=
541 _ (
542 "Failed to load our private key, falling back to signing via the PILS service\n"));
543
546 GDS_cfg);
551 NULL);
552 if (GNUNET_OK !=
554 {
556 return;
557 }
558}
559
560
561/* Finally, define the main method */
563
564
565/* 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)]
void GDS_helper_cleanup_operations(void)
Definition dht_helper.c:81
Helper functions for DHT.
struct GNUNET_PILS_Handle * GDS_pils
Handle for the pils service.
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.
struct GNUNET_SCHEDULER_Task * shutdown_task
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
static void pid_change_cb(void *cls, const struct GNUNET_HELLO_Parser *parser, const struct GNUNET_HashCode *hash)
static void load_underlay(void *cls, const char *section)
Function iterating over all configuration sections.
double GDS_NSE_get(void)
Return the current NSE.
struct GNUNET_MessageHeader * GDS_my_hello
Our HELLO.
static bool serving_clients
Are we already serving clients? We suspend the service until PILS told us our peer identity,...
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.
static struct PilsRequest * pils_requests_head
PILS Operation DLL.
static struct GDS_Underlay * u_head
Handles for the DHT underlays.
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.
static struct PilsRequest * pils_requests_tail
PILS Operation DLL.
static void run(void *cls, const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_SERVICE_Handle *service)
Process dht requests.
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.
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...
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.
#define MINIMUM_LOG_NSE
Floor for the log of the network size estimate, and the value we use before the NSE service has told ...
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 void update_network_size_estimate()
We've sent on our flood message or one that we received which was validated and closer than ours.
static struct GNUNET_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.
enum GNUNET_GenericReturnValue GNUNET_PILS_enable_private_key(struct GNUNET_PILS_Handle *handle)
Enable local access to the private key of the current peer identity.
Definition pils_api.c:896
struct GNUNET_PILS_Handle * GNUNET_PILS_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_PILS_PidChangeCallback pid_change_cb, void *cls)
Connect to the PILS service.
Definition pils_api.c:624
void GNUNET_PILS_disconnect(struct GNUNET_PILS_Handle *handle)
Disconnect from the PILS service.
Definition pils_api.c:647
void GNUNET_PILS_cancel(struct GNUNET_PILS_Operation *op)
Cancel request.
Definition pils_api.c:776
const struct GNUNET_PeerIdentity * GNUNET_PILS_get_identity(const struct GNUNET_PILS_Handle *handle)
Return the current peer identity of a given handle.
Definition pils_api.c:875
API to create, modify and access statistics.
void GNUNET_BLOCK_context_destroy(struct GNUNET_BLOCK_Context *ctx)
Destroy the block context.
Definition block.c:158
struct GNUNET_BLOCK_Context * GNUNET_BLOCK_context_create(const struct GNUNET_CONFIGURATION_Handle *cfg)
Create a block context.
Definition block.c:140
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".
#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.
struct GNUNET_MessageHeader * GNUNET_HELLO_parser_to_dht_hello_msg(const struct GNUNET_HELLO_Parser *parser)
Generate DHT HELLO message from a parser.
Definition hello-uri.c:1236
#define GNUNET_log(kind,...)
#define GNUNET_MAX(a, b)
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#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.
@ 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:572
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:1345
void(* GNUNET_SCHEDULER_TaskCallback)(void *cls)
Signature of the main function of a task.
void GNUNET_SERVICE_suspend(struct GNUNET_SERVICE_Handle *sh)
Suspend accepting connections from the listen socket temporarily.
Definition service.c:2381
void GNUNET_SERVICE_resume(struct GNUNET_SERVICE_Handle *sh)
Resume accepting connections from the listen socket.
Definition service.c:2389
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 _(String)
GNU gettext support macro.
Definition platform.h:179
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.
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 parsing HELLOs.
Definition hello-uri.c:233
A 512-bit hashcode.
Header for all communications.
The identity of the host (wraps the signing key of the peer).
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.
struct GNUNET_PILS_Operation * op
The pils operation.
struct PilsRequest * next
DLL.
struct PilsRequest * prev
DLL.