GNUnet  0.11.x
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_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"
34 #include "gnunet-service-dht.h"
38 
43 #define HELLO_FREQUENCY GNUNET_TIME_UNIT_HOURS
44 
45 
50 {
51 
55  struct GDS_Underlay *next;
56 
60  struct GDS_Underlay *prev;
61 
66 
71 
76 
80  char *name;
81 
85  char *libname;
86 };
87 
88 
92 struct MyAddress
93 {
97  struct MyAddress *next;
98 
102  struct MyAddress *prev;
103 
108 
112  char *url;
113 
117  struct GDS_Underlay *u;
118 };
119 
120 
125 
130 
135 
140 
145 
149 static struct GDS_Underlay *u_head;
150 
154 static struct GDS_Underlay *u_tail;
155 
159 static struct MyAddress *a_head;
160 
164 static struct MyAddress *a_tail;
165 
171 
172 
182 static void
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 
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)
203  else
205 }
206 
207 
213 double
215 {
217 }
218 
219 
221 
222 
228 static void
229 broadcast_hello (void *cls)
230 {
231  struct GNUNET_MessageHeader *hello;
232 
233  (void) cls;
234  /* TODO: randomize! */
237  NULL);
240  if (NULL == hello)
241  {
242  GNUNET_break (0);
243  return;
244  }
245  GDS_NEIGHBOURS_broadcast (hello);
246  GNUNET_free (hello);
247 }
248 
249 
259 static void
260 u_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 
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;
276  a_tail,
277  a);
278  *ctx = a;
280  address);
281  if (NULL != hello_task)
284  NULL);
285 }
286 
287 
293 static void
295 {
296  struct MyAddress *a = ctx;
297 
299  "Underlay deletes address %s for this peer\n",
300  a->url);
302  a->url);
304  a_tail,
305  a);
306  GNUNET_free (a->url);
307  GNUNET_free (a);
308  if (NULL != hello_task)
311  NULL);
312 }
313 
314 
315 void
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 
328 void
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 
345 void
348 {
349  u->dhtu->drop (ph);
350 }
351 
352 
355  struct GNUNET_DHTU_Target *target)
356 {
357  return u->dhtu->hold (u->dhtu->cls,
358  target);
359 }
360 
361 
367 static void
368 shutdown_task (void *cls)
369 {
370  struct GDS_Underlay *u;
371 
372  while (NULL != (u = u_head))
373  {
375  u->dhtu);
377  u_tail,
378  u);
379  GNUNET_free (u->name);
380  GNUNET_free (u->libname);
381  GNUNET_free (u);
382  }
385  GDS_ROUTING_done ();
386  if (NULL != GDS_block_context)
387  {
389  GDS_block_context = NULL;
390  }
391  GDS_CLIENTS_stop ();
392  if (NULL != GDS_stats)
393  {
395  GNUNET_YES);
396  GDS_stats = NULL;
397  }
398  if (NULL != GDS_my_hello)
399  {
401  GDS_my_hello = NULL;
402  }
403  if (NULL != hello_task)
404  {
406  hello_task = NULL;
407  }
408 }
409 
410 
418 static void
419 load_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 !=
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;
446  "libgnunet_plugin_dhtu_%s",
447  section);
449  &u->env);
450  if (NULL == u->dhtu)
451  {
453  GNUNET_free (u);
454  return;
455  }
456  u->libname = libname;
457  u->name = GNUNET_strdup (section);
459  u_tail,
460  u);
461 }
462 
463 
471 static void
472 run (void *cls,
473  const struct GNUNET_CONFIGURATION_Handle *c,
475 {
476  GDS_cfg = c;
478  {
479  char *keyfile;
480 
481  if (GNUNET_OK !=
483  "PEER",
484  "PRIVATE_KEY",
485  &keyfile))
486  {
488  "PEER",
489  "PRIVATE_KEY");
491  return;
492  }
493  if (GNUNET_SYSERR ==
495  GNUNET_YES,
497  {
499  "Failed to setup peer's private key\n");
500  GNUNET_free (keyfile);
502  return;
503  }
504  GNUNET_free (keyfile);
505  }
510  sizeof(struct GNUNET_PeerIdentity),
514  GDS_cfg);
515  GDS_CLIENTS_init ();
516  GDS_ROUTING_init ();
519  NULL);
520  if (GNUNET_OK !=
522  {
524  return;
525  }
527  &load_underlay,
528  NULL);
529  if (NULL == u_head)
530  {
532  "No DHT underlays configured!\n");
534  return;
535  }
536 }
537 
538 
539 /* Finally, define the main method */
541 
542 
543 /* end of gnunet-service-dht.c */
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static struct GNUNET_ATS_PerformanceHandle * ph
ATS performance handle used.
Definition: gnunet-ats.c:116
static char * address
GNS address for this phone.
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_DHTU_PreferenceHandle * GDS_u_hold(struct GDS_Underlay *u, struct GNUNET_DHTU_Target *target)
Create a hold on target at underlay u.
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.
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.
static void GDS_CLIENTS_init(void)
Initialize client subsystem.
static 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:37
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
#define GNUNET_log(kind,...)
#define GNUNET_MAX(a, b)
@ GNUNET_OK
Definition: gnunet_common.h:95
@ GNUNET_YES
Definition: gnunet_common.h:97
@ GNUNET_NO
Definition: gnunet_common.h:94
@ GNUNET_SYSERR
Definition: gnunet_common.h:93
void GNUNET_BLOCK_context_destroy(struct GNUNET_BLOCK_Context *ctx)
Destroy the block context.
Definition: block.c:134
struct GNUNET_BLOCK_Context * GNUNET_BLOCK_context_create(const struct GNUNET_CONFIGURATION_Handle *cfg)
Create a block context.
Definition: block.c:118
void GNUNET_CONFIGURATION_iterate_sections(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_CONFIGURATION_Section_Iterator iter, void *iter_cls)
Iterate over all sections in the configuration.
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.
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:197
#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:312
struct GNUNET_MessageHeader * GNUNET_HELLO_builder_to_dht_hello_msg(const struct GNUNET_HELLO_Builder *builder, const struct GNUNET_CRYPTO_EddsaPrivateKey *priv)
Generate DHT HELLO message (without peer ID) from a builder.
Definition: hello-uri.c:579
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:791
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:741
struct GNUNET_HELLO_Builder * GNUNET_HELLO_builder_new(const struct GNUNET_PeerIdentity *pid)
Allocate builder.
Definition: hello-uri.c:301
#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_ERROR
@ GNUNET_ERROR_TYPE_INFO
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#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_PLUGIN_unload(const char *library_name, void *arg)
Unload plugin (runs the "done" callback and returns whatever "done" returned).
Definition: plugin.c:269
void * GNUNET_PLUGIN_load(const char *library_name, void *arg)
Setup plugin (runs the "init" callback and returns whatever "init" returned).
Definition: plugin.c:217
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:531
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:1296
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:1331
void(* GNUNET_SCHEDULER_TaskCallback)(void *cls)
Signature of the main function of a task.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:972
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:1269
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).
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 * libname
Name of the library providing the 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 ...
void(* address_add_cb)(void *cls, const char *address, struct GNUNET_DHTU_Source *source, void **ctx)
Function to call with new addresses of this peer.
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration to use.
void(* connect_cb)(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.
void * cls
Closure to use for callbacks.
void(* address_del_cb)(void *ctx)
Function to call with expired addresses of this peer.
void(* disconnect_cb)(void *ctx)
Function to call when we disconnected from a peer and can henceforth cannot transmit to that peer any...
void(* network_size_cb)(void *cls, struct GNUNET_TIME_Absolute timestamp, double logestimate, double std_dev)
We have a new estimate on the size of the underlay.
void(* receive_cb)(void *cls, void **tctx, void **sctx, const void *message, size_t message_size)
Function to call when we receive a message.
struct returned by the initialization function of the plugin
struct GNUNET_DHTU_PreferenceHandle *(* hold)(void *cls, struct GNUNET_DHTU_Target *target)
Request underlay to keep the connection to target alive if possible.
void(* try_connect)(void *cls, const struct GNUNET_PeerIdentity *pid, const char *address)
Request creation of a session with a peer at the given address.
void * cls
Closure to pass to all plugin functions.
void(* drop)(struct GNUNET_DHTU_PreferenceHandle *ph)
Do no longer request underlay to keep the connection alive.
void(* send)(void *cls, 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.
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:184
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:117
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.