GNUnet  0.11.x
Data Structures | Macros | Functions
plugin_dhtu_ip.c File Reference

plain IP based DHT network underlay More...

#include "platform.h"
#include "gnunet_dhtu_plugin.h"
Include dependency graph for plugin_dhtu_ip.c:

Go to the source code of this file.

Data Structures

struct  GNUNET_DHTU_Source
 Opaque handle that the underlay offers for our address to be used when sending messages to another peer. More...
 
struct  GNUNET_DHTU_Target
 Opaque handle that the underlay offers for the target peer when sending messages to another peer. More...
 
struct  GNUNET_DHTU_PreferenceHandle
 Opaque handle expressing a preference of the DHT to keep a particular target connected. More...
 
struct  Plugin
 Handle for a plugin. More...
 

Macros

#define SCAN_FREQ   GNUNET_TIME_UNIT_MINUTES
 How frequently should we re-scan our local interfaces for IPs? More...
 
#define MAX_DESTS   256
 Maximum number of concurrently active destinations to support. More...
 

Functions

static ssize_t ip_sign (void *cls, const struct GNUNET_DHTU_PrivateKey *pk, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, void **sig)
 Use our private key to sign a message. More...
 
static enum GNUNET_GenericReturnValue ip_verify (void *cls, const struct GNUNET_DHTU_PublicKey *pk, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, const void *sig, size_t sig_size)
 Verify signature in sig over purpose. More...
 
static struct GNUNET_DHTU_Targetcreate_target (struct Plugin *plugin, const struct sockaddr *addr, socklen_t addrlen)
 Create a target to which we may send traffic. More...
 
static struct GNUNET_DHTU_Targetfind_target (struct Plugin *plugin, const void *addr, size_t addrlen)
 Find target matching addr. More...
 
static void ip_try_connect (void *cls, const char *address)
 Request creation of a session with a peer at the given address. More...
 
static struct GNUNET_DHTU_PreferenceHandleip_hold (void *cls, struct GNUNET_DHTU_Target *target)
 Request underlay to keep the connection to target alive if possible. More...
 
static void ip_drop (struct GNUNET_DHTU_PreferenceHandle *ph)
 Do no long request underlay to keep the connection alive. More...
 
static void ip_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. More...
 
static struct GNUNET_DHTU_Sourcecreate_source (struct Plugin *plugin, const struct sockaddr *addr, socklen_t addrlen)
 Create a new source on which we may be receiving traffic. More...
 
static int process_ifcs (void *cls, const char *name, int isDefault, const struct sockaddr *addr, const struct sockaddr *broadcast_addr, const struct sockaddr *netmask, socklen_t addrlen)
 Callback function invoked for each interface found. More...
 
static void scan (void *cls)
 Scan network interfaces for IP address changes. More...
 
static struct GNUNET_DHTU_Sourcefind_source (struct Plugin *plugin, const void *addr, size_t addrlen)
 Find our source matching addr. More...
 
static void read_cb (void *cls)
 UDP socket is ready to receive. More...
 
void * libgnunet_plugin_dhtu_ip_init (void *cls)
 Entry point for the plugin. More...
 
void * libgnunet_plugin_dhtu_ip_done (void *cls)
 Exit point from the plugin. More...
 

Detailed Description

plain IP based DHT network underlay

Author
Christian Grothoff

Definition in file plugin_dhtu_ip.c.

Macro Definition Documentation

◆ SCAN_FREQ

#define SCAN_FREQ   GNUNET_TIME_UNIT_MINUTES

How frequently should we re-scan our local interfaces for IPs?

Definition at line 33 of file plugin_dhtu_ip.c.

◆ MAX_DESTS

#define MAX_DESTS   256

Maximum number of concurrently active destinations to support.

Definition at line 38 of file plugin_dhtu_ip.c.

Function Documentation

◆ ip_sign()

static ssize_t ip_sign ( void *  cls,
const struct GNUNET_DHTU_PrivateKey pk,
const struct GNUNET_CRYPTO_EccSignaturePurpose purpose,
void **  sig 
)
static

Use our private key to sign a message.

Parameters
clsclosure
pkour private key to sign with
purposewhat to sign
[out]signature,allocatedon heap and returned
Returns
-1 on error, otherwise number of bytes in sig

Definition at line 241 of file plugin_dhtu_ip.c.

245 {
246  return 0;
247 }

Referenced by libgnunet_plugin_dhtu_ip_init().

Here is the caller graph for this function:

◆ ip_verify()

static enum GNUNET_GenericReturnValue ip_verify ( void *  cls,
const struct GNUNET_DHTU_PublicKey pk,
const struct GNUNET_CRYPTO_EccSignaturePurpose purpose,
const void *  sig,
size_t  sig_size 
)
static

Verify signature in sig over purpose.

Parameters
clsclosure
pkpublic key to verify signature of
purposewhat was being signed
sigsignature data
sig_sizenumber of bytes in sig
Returns
GNUNET_OK if signature is valid GNUNET_NO if signatures are not supported GNUNET_SYSERR if signature is invalid

Definition at line 241 of file plugin_dhtu_ip.c.

268 {
269  return GNUNET_NO;
270 }
@ GNUNET_NO
Definition: gnunet_common.h:94

Referenced by libgnunet_plugin_dhtu_ip_init().

Here is the caller graph for this function:

◆ create_target()

static struct GNUNET_DHTU_Target* create_target ( struct Plugin plugin,
const struct sockaddr *  addr,
socklen_t  addrlen 
)
static

Create a target to which we may send traffic.

Parameters
pluginour plugin
addrtarget address
addrlennumber of bytes in addr
Returns
new target object

Definition at line 282 of file plugin_dhtu_ip.c.

285 {
286  static struct GNUNET_DHTU_PublicKey pk;
287  struct GNUNET_DHTU_Target *dst;
288 
289  if (MAX_DESTS >
291  {
292  struct GNUNET_HashCode key;
293 
294  dst = NULL;
295  for (struct GNUNET_DHTU_Target *pos = plugin->dst_head;
296  NULL != pos;
297  pos = pos->next)
298  {
299  /* >= here assures we remove oldest entries first */
300  if ( (NULL == dst) ||
301  (dst->ph_count >= pos->ph_count) )
302  dst = pos;
303  }
304  GNUNET_assert (NULL != dst);
305  plugin->env->disconnect_cb (dst->app_ctx);
306  GNUNET_CRYPTO_hash (&dst->addr,
307  dst->addrlen,
308  &key);
311  &key,
312  dst));
314  plugin->dst_tail,
315  dst);
316  GNUNET_assert (NULL == dst->ph_head);
317  GNUNET_free (dst);
318  }
319  pk.size = htons (sizeof (pk));
320  dst = GNUNET_new (struct GNUNET_DHTU_Target);
321  dst->addrlen = addrlen;
322  memcpy (&dst->addr,
323  addr,
324  addrlen);
325  switch (addr->sa_family)
326  {
327  case AF_INET:
328  {
329  const struct sockaddr_in *s4 = (const struct sockaddr_in *) addr;
330 
331  GNUNET_assert (sizeof (struct sockaddr_in) == addrlen);
332  GNUNET_CRYPTO_hash (&s4->sin_addr,
333  sizeof (struct in_addr),
334  &dst->id.hc);
335  }
336  break;
337  case AF_INET6:
338  {
339  const struct sockaddr_in6 *s6 = (const struct sockaddr_in6 *) addr;
340 
341  GNUNET_assert (sizeof (struct sockaddr_in6) == addrlen);
342  GNUNET_CRYPTO_hash (&s6->sin6_addr,
343  sizeof (struct in6_addr),
344  &dst->id.hc);
345  }
346  break;
347  default:
348  GNUNET_break (0);
349  GNUNET_free (dst);
350  return NULL;
351  }
353  plugin->dst_tail,
354  dst);
355  plugin->env->connect_cb (plugin->env->cls,
356  &pk,
357  &dst->id,
358  dst,
359  &dst->app_ctx);
360  return dst;
361 }
struct Plugin * plugin
The process handle to the testbed service.
struct GNUNET_HashCode key
The key used in the DHT.
struct GNUNET_IDENTITY_PrivateKey pk
Private key from command line option, or NULL.
@ GNUNET_YES
Definition: gnunet_common.h:97
#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
int GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
#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.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
#define MAX_DESTS
Maximum number of concurrently active destinations to support.
void * cls
Closure to use for callbacks.
Handle for a public key used by another peer.
Opaque handle that the underlay offers for the target peer when sending messages to another peer.
struct GNUNET_DHTU_Target * next
Kept in a DLL.
A 512-bit hashcode.
struct GNUNET_CONTAINER_MultiHashMap * dsts
Map from hashes of sockaddrs to targets.
struct GNUNET_DHTU_Target * dst_tail
Tail of destinations that are active.
struct GNUNET_DATACACHE_PluginEnvironment * env
Our execution environment.
struct GNUNET_DHTU_Target * dst_head
Head of destinations that are active.

References GNUNET_DHTU_Target::addr, GNUNET_DHTU_Target::addrlen, GNUNET_DHTU_Target::app_ctx, GNUNET_DATACACHE_PluginEnvironment::cls, Plugin::dst_head, Plugin::dst_tail, Plugin::dsts, Plugin::env, GNUNET_assert, GNUNET_break, GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_DLL_remove, GNUNET_CONTAINER_multihashmap_remove(), GNUNET_CONTAINER_multihashmap_size(), GNUNET_CRYPTO_hash(), GNUNET_free, GNUNET_new, GNUNET_YES, GNUNET_DHTU_Hash::hc, GNUNET_DHTU_Target::id, key, MAX_DESTS, GNUNET_DHTU_Target::next, pk, and plugin.

Referenced by find_target().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_target()

static struct GNUNET_DHTU_Target* find_target ( struct Plugin plugin,
const void *  addr,
size_t  addrlen 
)
static

Find target matching addr.

If none exists, create one!

Parameters
pluginthe plugin handle
srcsource target is from, or NULL if unknown
addrsocket address to find
addrlennumber of bytes in addr
Returns
matching target object

Definition at line 375 of file plugin_dhtu_ip.c.

378 {
379  struct GNUNET_HashCode key;
380  struct GNUNET_DHTU_Target *dst;
381 
383  addrlen,
384  &key);
386  &key);
387  if (NULL == dst)
388  {
389  dst = create_target (plugin,
390  (const struct sockaddr *) addr,
391  addrlen);
394  plugin->dsts,
395  &key,
396  dst,
398  }
399  else
400  {
401  /* move to head of DLL */
403  plugin->dst_tail,
404  dst);
406  plugin->dst_tail,
407  dst);
408 
409  }
410  return dst;
411 }
int GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
There must only be one value per key; storing a value should fail if a value under the same key alrea...
static struct GNUNET_DHTU_Target * create_target(struct Plugin *plugin, const struct sockaddr *addr, socklen_t addrlen)
Create a target to which we may send traffic.
socklen_t addrlen
Number of bytes in addr.
struct sockaddr_storage addr
Target IP address.

References GNUNET_DHTU_Target::addr, GNUNET_DHTU_Target::addrlen, create_target(), Plugin::dst_head, Plugin::dst_tail, Plugin::dsts, GNUNET_assert, GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_DLL_remove, GNUNET_CONTAINER_multihashmap_get(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_CRYPTO_hash(), GNUNET_YES, key, and plugin.

Referenced by ip_try_connect(), and read_cb().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ip_try_connect()

static void ip_try_connect ( void *  cls,
const char *  address 
)
static

Request creation of a session with a peer at the given address.

Parameters
clsclosure (internal context for the plugin)
addresstarget address to connect to

Definition at line 421 of file plugin_dhtu_ip.c.

423 {
424  struct Plugin *plugin = cls;
425  char *colon;
426  const char *port;
427  char *addr;
428  struct addrinfo hints = {
429  .ai_flags = AI_NUMERICHOST | AI_NUMERICSERV
430  };
431  struct addrinfo *result = NULL;
432 
433  if (0 !=
434  strncmp (address,
435  "ip+",
436  strlen ("ip+")))
437  {
438  GNUNET_break (0);
439  return;
440  }
441  address += strlen ("ip+");
442  if (0 !=
443  strncmp (address,
444  "udp://",
445  strlen ("udp://")))
446  {
447  GNUNET_break (0);
448  return;
449  }
450  address += strlen ("udp://");
451  addr = GNUNET_strdup (address);
452  colon = strchr (addr, ':');
453  if (NULL == colon)
454  {
455  port = plugin->port;
456  }
457  else
458  {
459  *colon = '\0';
460  port = colon + 1;
461  }
462  if (0 !=
463  getaddrinfo (addr,
464  port,
465  &hints,
466  &result))
467  {
468  GNUNET_break (0);
469  GNUNET_free (addr);
470  return;
471  }
472  GNUNET_free (addr);
473  (void) find_target (plugin,
474  result->ai_addr,
475  result->ai_addrlen);
476  freeaddrinfo (result);
477 }
static uint16_t port
Port number.
Definition: gnunet-bcd.c:83
static char * address
GNS address for this phone.
static int result
Global testing status.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define AI_NUMERICSERV
AI_NUMERICSERV not defined in windows.
Definition: platform.h:218
static struct GNUNET_DHTU_Target * find_target(struct Plugin *plugin, const void *addr, size_t addrlen)
Find target matching addr.
Handle for a plugin.
Definition: block.c:38
char * port
Port we bind to.

References address, AI_NUMERICSERV, find_target(), GNUNET_break, GNUNET_free, GNUNET_strdup, plugin, Plugin::port, port, and result.

Referenced by libgnunet_plugin_dhtu_ip_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ip_hold()

static struct GNUNET_DHTU_PreferenceHandle* ip_hold ( void *  cls,
struct GNUNET_DHTU_Target target 
)
static

Request underlay to keep the connection to target alive if possible.

Hold may be called multiple times to express a strong preference to keep a connection, say because a target is in multiple tables.

Parameters
clsclosure
targetconnection to keep alive

Definition at line 489 of file plugin_dhtu_ip.c.

491 {
493 
495  ph->target = target;
497  target->ph_tail,
498  ph);
499  target->ph_count++;
500  return ph;
501 }
static struct GNUNET_ATS_PerformanceHandle * ph
ATS performance handle used.
Definition: gnunet-ats.c:116
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.
struct GNUNET_DHTU_PreferenceHandle * ph_head
Head of preferences expressed for this target.
unsigned int ph_count
Preference counter, length of the ph_head DLL.
struct GNUNET_DHTU_PreferenceHandle * ph_tail
Tail of preferences expressed for this target.

References GNUNET_CONTAINER_DLL_insert, GNUNET_new, ph, GNUNET_DHTU_Target::ph_count, GNUNET_DHTU_Target::ph_head, GNUNET_DHTU_Target::ph_tail, and GNUNET_DHTU_PreferenceHandle::target.

Referenced by libgnunet_plugin_dhtu_ip_init().

Here is the caller graph for this function:

◆ ip_drop()

static void ip_drop ( struct GNUNET_DHTU_PreferenceHandle ph)
static

Do no long request underlay to keep the connection alive.

Parameters
clsclosure
targetconnection to keep alive

Definition at line 511 of file plugin_dhtu_ip.c.

512 {
513  struct GNUNET_DHTU_Target *target = ph->target;
514 
516  target->ph_tail,
517  ph);
518  target->ph_count--;
519  GNUNET_free (ph);
520 }

References GNUNET_CONTAINER_DLL_remove, GNUNET_free, ph, GNUNET_DHTU_Target::ph_count, GNUNET_DHTU_Target::ph_head, and GNUNET_DHTU_Target::ph_tail.

Referenced by libgnunet_plugin_dhtu_ip_init().

Here is the caller graph for this function:

◆ ip_send()

static void ip_send ( void *  cls,
struct GNUNET_DHTU_Target target,
const void *  msg,
size_t  msg_size,
GNUNET_SCHEDULER_TaskCallback  finished_cb,
void *  finished_cb_cls 
)
static

Send message to some other participant over the network.

Note that sending is not guaranteeing that the other peer actually received the message. For any given target, the DHT must wait for the finished_cb to be called before calling send() again.

Parameters
clsclosure (internal context for the plugin)
targetreceiver identification
msgmessage
msg_sizenumber of bytes in msg
finished_cbfunction called once transmission is done (not called if target disconnects, then only the disconnect_cb is called).
finished_cb_clsclosure for finished_cb

Definition at line 539 of file plugin_dhtu_ip.c.

545 {
546  struct Plugin *plugin = cls;
547 
549  msg,
550  msg_size,
551  (const struct sockaddr *) &target->addr,
552  target->addrlen);
553  finished_cb (finished_cb_cls);
554 }
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
ssize_t GNUNET_NETWORK_socket_sendto(const struct GNUNET_NETWORK_Handle *desc, const void *message, size_t length, const struct sockaddr *dest_addr, socklen_t dest_len)
Send data to a particular destination (always non-blocking).
Definition: network.c:846
struct GNUNET_NETWORK_Handle * sock
My UDP socket.

References GNUNET_DHTU_Target::addr, GNUNET_DHTU_Target::addrlen, GNUNET_NETWORK_socket_sendto(), msg, plugin, and Plugin::sock.

Referenced by libgnunet_plugin_dhtu_ip_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ create_source()

static struct GNUNET_DHTU_Source* create_source ( struct Plugin plugin,
const struct sockaddr *  addr,
socklen_t  addrlen 
)
static

Create a new source on which we may be receiving traffic.

Parameters
pluginour plugin
addrour address
addrlennumber of bytes in addr
Returns
new source object

Definition at line 566 of file plugin_dhtu_ip.c.

569 {
570  struct GNUNET_DHTU_Source *src;
571 
572  src = GNUNET_new (struct GNUNET_DHTU_Source);
573  src->addrlen = addrlen;
574  memcpy (&src->addr,
575  addr,
576  addrlen);
578  switch (addr->sa_family)
579  {
580  case AF_INET:
581  {
582  const struct sockaddr_in *s4 = (const struct sockaddr_in *) addr;
583  char buf[INET_ADDRSTRLEN];
584 
585  GNUNET_assert (sizeof (struct sockaddr_in) == addrlen);
586  GNUNET_CRYPTO_hash (&s4->sin_addr,
587  sizeof (struct in_addr),
588  &src->id.hc);
589  GNUNET_asprintf (&src->address,
590  "ip+udp://%s:%u",
591  inet_ntop (AF_INET,
592  &s4->sin_addr,
593  buf,
594  sizeof (buf)),
595  ntohs (s4->sin_port));
596  }
597  break;
598  case AF_INET6:
599  {
600  const struct sockaddr_in6 *s6 = (const struct sockaddr_in6 *) addr;
601  char buf[INET6_ADDRSTRLEN];
602 
603  GNUNET_assert (sizeof (struct sockaddr_in6) == addrlen);
604  GNUNET_CRYPTO_hash (&s6->sin6_addr,
605  sizeof (struct in6_addr),
606  &src->id.hc);
607  GNUNET_asprintf (&src->address,
608  "ip+udp://[%s]:%u",
609  inet_ntop (AF_INET6,
610  &s6->sin6_addr,
611  buf,
612  sizeof (buf)),
613  ntohs (s6->sin6_port));
614  }
615  break;
616  default:
617  GNUNET_break (0);
618  GNUNET_free (src);
619  return NULL;
620  }
622  plugin->src_tail,
623  src);
624  plugin->env->address_add_cb (plugin->env->cls,
625  &src->id,
626  NULL, /* no key */
627  src->address,
628  src,
629  &src->app_ctx);
630  return src;
631 }
static char buf[2048]
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
struct GNUNET_HashCode hc
For now, use a 512 bit hash.
Opaque handle that the underlay offers for our address to be used when sending messages to another pe...
struct GNUNET_DHTU_Hash id
Hash of the IP address.
void * app_ctx
Application context for this source.
socklen_t addrlen
Number of bytes in addr.
char * address
Address in URL form ("ip+udp://$IP:$PORT")
struct sockaddr_storage addr
My actual address.
unsigned int scan_generation
Last generation this address was observed.
unsigned int scan_generation
How often have we scanned for IPs?
struct GNUNET_DHTU_Source * src_tail
Tail of sources where we receive traffic.
struct GNUNET_DHTU_Source * src_head
Head of sources where we receive traffic.

References GNUNET_DHTU_Source::addr, GNUNET_DHTU_Source::address, GNUNET_DHTU_Source::addrlen, GNUNET_DHTU_Source::app_ctx, buf, GNUNET_DATACACHE_PluginEnvironment::cls, Plugin::env, GNUNET_asprintf(), GNUNET_assert, GNUNET_break, GNUNET_CONTAINER_DLL_insert, GNUNET_CRYPTO_hash(), GNUNET_free, GNUNET_new, GNUNET_DHTU_Hash::hc, GNUNET_DHTU_Source::id, plugin, GNUNET_DHTU_Source::scan_generation, Plugin::scan_generation, Plugin::src_head, and Plugin::src_tail.

Referenced by find_source(), and process_ifcs().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_ifcs()

static int process_ifcs ( void *  cls,
const char *  name,
int  isDefault,
const struct sockaddr *  addr,
const struct sockaddr *  broadcast_addr,
const struct sockaddr *  netmask,
socklen_t  addrlen 
)
static

Callback function invoked for each interface found.

Parameters
clsclosure
namename of the interface (can be NULL for unknown)
isDefaultis this presumably the default interface
addraddress of this interface (can be NULL for unknown or unassigned)
broadcast_addrthe broadcast address (can be NULL for unknown or unassigned)
netmaskthe network mask (can be NULL for unknown or unassigned)
addrlenlength of the address
Returns
GNUNET_OK to continue iteration, GNUNET_SYSERR to abort

Definition at line 647 of file plugin_dhtu_ip.c.

654 {
655  struct Plugin *plugin = cls;
656  struct GNUNET_DHTU_Source *src;
657 
658  for (src = plugin->src_head;
659  NULL != src;
660  src = src->next)
661  {
662  if ( (addrlen == src->addrlen) &&
663  (0 == memcmp (addr,
664  &src->addr,
665  addrlen)) )
666  {
668  return GNUNET_OK;
669  }
670  }
671  (void) create_source (plugin,
672  addr,
673  addrlen);
674  return GNUNET_OK;
675 }
@ GNUNET_OK
Definition: gnunet_common.h:95
static struct GNUNET_DHTU_Source * create_source(struct Plugin *plugin, const struct sockaddr *addr, socklen_t addrlen)
Create a new source on which we may be receiving traffic.
struct GNUNET_DHTU_Source * next
Kept in a DLL.

References GNUNET_DHTU_Source::addr, GNUNET_DHTU_Source::addrlen, create_source(), GNUNET_OK, GNUNET_DHTU_Source::next, plugin, GNUNET_DHTU_Source::scan_generation, Plugin::scan_generation, and Plugin::src_head.

Referenced by scan().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ scan()

static void scan ( void *  cls)
static

Scan network interfaces for IP address changes.

Parameters
clsa struct Plugin

Definition at line 684 of file plugin_dhtu_ip.c.

685 {
686  struct Plugin *plugin = cls;
687  struct GNUNET_DHTU_Source *next;
688 
691  plugin);
692  for (struct GNUNET_DHTU_Source *src = plugin->src_head;
693  NULL != src;
694  src = next)
695  {
696  next = src->next;
697  if (src->scan_generation == plugin->scan_generation)
698  continue;
700  plugin->src_tail,
701  src);
702  plugin->env->address_del_cb (src->app_ctx);
703  GNUNET_free (src->address);
704  GNUNET_free (src);
705  }
707  &scan,
708  plugin);
709 }
void GNUNET_OS_network_interfaces_list(GNUNET_OS_NetworkInterfaceProcessor proc, void *proc_cls)
Enumerate all network interfaces.
Definition: os_network.c:396
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
static void scan(void *cls)
Scan network interfaces for IP address changes.
#define SCAN_FREQ
How frequently should we re-scan our local interfaces for IPs?
static int process_ifcs(void *cls, const char *name, int isDefault, const struct sockaddr *addr, const struct sockaddr *broadcast_addr, const struct sockaddr *netmask, socklen_t addrlen)
Callback function invoked for each interface found.
struct GNUNET_SCHEDULER_Task * scan_task
Task that scans for IP address changes.

References Plugin::env, GNUNET_CONTAINER_DLL_remove, GNUNET_free, GNUNET_OS_network_interfaces_list(), GNUNET_SCHEDULER_add_delayed(), GNUNET_DHTU_Source::next, plugin, process_ifcs(), SCAN_FREQ, Plugin::scan_generation, Plugin::scan_task, Plugin::src_head, and Plugin::src_tail.

Referenced by libgnunet_plugin_dhtu_ip_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_source()

static struct GNUNET_DHTU_Source* find_source ( struct Plugin plugin,
const void *  addr,
size_t  addrlen 
)
static

Find our source matching addr.

If none exists, create one!

Parameters
pluginthe plugin handle
addrsocket address to find
addrlennumber of bytes in addr
Returns
matching source object

Definition at line 722 of file plugin_dhtu_ip.c.

725 {
726  for (struct GNUNET_DHTU_Source *src = plugin->src_head;
727  NULL != src;
728  src = src->next)
729  {
730  if ( (addrlen == src->addrlen) &&
731  (0 == memcmp (addr,
732  &src->addr,
733  addrlen)) )
734  return src;
735  }
736 
737  return create_source (plugin,
738  (const struct sockaddr *) addr,
739  addrlen);
740 }

References GNUNET_DHTU_Source::addr, GNUNET_DHTU_Source::addrlen, create_source(), GNUNET_DHTU_Source::next, plugin, and Plugin::src_head.

Referenced by read_cb().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ read_cb()

static void read_cb ( void *  cls)
static

UDP socket is ready to receive.

Read.

Parameters
clsour struct Plugin *

Definition at line 749 of file plugin_dhtu_ip.c.

750 {
751  struct Plugin *plugin = cls;
752  ssize_t ret;
753  char buf[65536];
754  struct sockaddr_storage sa;
755  struct iovec iov = {
756  .iov_base = buf,
757  .iov_len = sizeof (buf)
758  };
759  char ctl[128];
760  struct msghdr mh = {
761  .msg_name = &sa,
762  .msg_namelen = sizeof (sa),
763  .msg_iov = &iov,
764  .msg_iovlen = 1,
765  .msg_control = ctl,
766  .msg_controllen = sizeof (ctl)
767  };
768 
769  ret = recvmsg (GNUNET_NETWORK_get_fd (plugin->sock),
770  &mh,
771  MSG_DONTWAIT);
772  if (ret >= 0)
773  {
774  struct GNUNET_DHTU_Target *dst = NULL;
775  struct GNUNET_DHTU_Source *src = NULL;
776  struct cmsghdr *cmsg;
777 
778  /* find IP where we received message */
779  for (cmsg = CMSG_FIRSTHDR (&mh);
780  NULL != cmsg;
781  cmsg = CMSG_NXTHDR (&mh,
782  cmsg))
783  {
784  if ( (cmsg->cmsg_level == IPPROTO_IP) &&
785  (cmsg->cmsg_type == IP_PKTINFO) )
786  {
787  if (CMSG_LEN (sizeof (struct in_pktinfo)) ==
788  cmsg->cmsg_len)
789  {
790  struct in_pktinfo pi;
791 
792  memcpy (&pi,
793  CMSG_DATA (cmsg),
794  sizeof (pi));
795  {
796  struct sockaddr_in sa = {
797  .sin_family = AF_INET,
798  .sin_addr = pi.ipi_addr
799  };
800 
801  src = find_source (plugin,
802  &sa,
803  sizeof (sa));
804  }
805  break;
806  }
807  else
808  GNUNET_break (0);
809  }
810  if ( (cmsg->cmsg_level == IPPROTO_IPV6) &&
811  (cmsg->cmsg_type == IPV6_RECVPKTINFO) )
812  {
813  if (CMSG_LEN (sizeof (struct in6_pktinfo)) ==
814  cmsg->cmsg_len)
815  {
816  struct in6_pktinfo pi;
817 
818  memcpy (&pi,
819  CMSG_DATA (cmsg),
820  sizeof (pi));
821  {
822  struct sockaddr_in6 sa = {
823  .sin6_family = AF_INET6,
824  .sin6_addr = pi.ipi6_addr,
825  .sin6_scope_id = pi.ipi6_ifindex
826  };
827 
828  src = find_source (plugin,
829  &sa,
830  sizeof (sa));
831  break;
832  }
833  }
834  else
835  GNUNET_break (0);
836  }
837  }
838  dst = find_target (plugin,
839  &sa,
840  mh.msg_namelen);
841  if ( (NULL == src) ||
842  (NULL == dst) )
843  {
844  GNUNET_break (0);
845  }
846  else
847  {
848  plugin->env->receive_cb (plugin->env->cls,
849  dst->app_ctx,
850  src->app_ctx,
851  buf,
852  ret);
853  }
854  }
857  plugin->sock,
858  &read_cb,
859  plugin);
860 }
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static struct GNUNET_CADET_Handle * mh
Cadet handle.
Definition: gnunet-cadet.c:92
static struct GNUNET_PEERINFO_Handle * pi
Handle to peerinfo service.
int GNUNET_NETWORK_get_fd(const struct GNUNET_NETWORK_Handle *desc)
Return file descriptor for this network handle.
Definition: network.c:1075
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_read_net(struct GNUNET_TIME_Relative delay, struct GNUNET_NETWORK_Handle *rfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when the specified file descriptor is ready f...
Definition: scheduler.c:1517
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
static void read_cb(void *cls)
UDP socket is ready to receive.
static struct GNUNET_DHTU_Source * find_source(struct Plugin *plugin, const void *addr, size_t addrlen)
Find our source matching addr.
void * app_ctx
Application context for this target.
struct GNUNET_SCHEDULER_Task * read_task
Task that reads incoming UDP packets.

References GNUNET_DHTU_Source::app_ctx, GNUNET_DHTU_Target::app_ctx, buf, GNUNET_DATACACHE_PluginEnvironment::cls, Plugin::env, find_source(), find_target(), GNUNET_break, GNUNET_NETWORK_get_fd(), GNUNET_SCHEDULER_add_read_net(), GNUNET_TIME_UNIT_FOREVER_REL, mh, pi, plugin, Plugin::read_task, ret, and Plugin::sock.

Referenced by libgnunet_plugin_dhtu_ip_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ libgnunet_plugin_dhtu_ip_init()

void* libgnunet_plugin_dhtu_ip_init ( void *  cls)

Entry point for the plugin.

Parameters
clsclosure (the struct GNUNET_DHTU_PluginEnvironment)
Returns
the plugin's API

Definition at line 870 of file plugin_dhtu_ip.c.

871 {
873  struct GNUNET_DHTU_PluginFunctions *api;
874  struct Plugin *plugin;
875  char *port;
876  unsigned int nport;
877  int sock;
878  int af;
879  unsigned long long nse;
880 
881  if (GNUNET_OK !=
883  "DHTU-IP",
884  "NSE",
885  &nse))
886  {
888  "DHTU-IP",
889  "NSE");
890  return NULL;
891  }
892  if (GNUNET_OK !=
894  "DHTU-IP",
895  "UDP_PORT",
896  &port))
897  {
899  "DHTU-IP",
900  "UDP_PORT");
901  return NULL;
902  }
903  {
904  char dummy;
905 
906  if ( (1 != sscanf (port,
907  "%u%c",
908  &nport,
909  &dummy)) ||
910  (nport > UINT16_MAX) )
911  {
913  "DHTU-IP",
914  "UDP_PORT",
915  "must be number below 65536");
916  GNUNET_free (port);
917  return NULL;
918  }
919  }
920  plugin = GNUNET_new (struct Plugin);
921  plugin->env = env;
922  plugin->port = port;
923  af = AF_INET6;
924  sock = socket (af,
925  SOCK_DGRAM,
926  IPPROTO_UDP);
927  if (-1 == sock)
928  {
930  "socket");
933  return NULL;
934  }
935  switch (af)
936  {
937  case AF_INET:
938  {
939  int on = 1;
940 
941  if (0 !=
942  setsockopt (sock,
943  IPPROTO_IP,
944  IP_PKTINFO,
945  &on,
946  sizeof (on)))
947  {
949  "setsockopt");
950  }
951  }
952  {
953  struct sockaddr_in sa = {
954  .sin_family = AF_INET,
955  .sin_port = htons ((uint16_t) nport)
956  };
957 
958  if (0 !=
959  bind (sock,
960  (const struct sockaddr *) &sa,
961  sizeof (sa)))
962  {
964  "socket");
965  GNUNET_break (0 ==
966  close (sock));
969  return NULL;
970  }
971  }
972  break;
973  case AF_INET6:
974  {
975  int on = 1;
976 
977  if (0 !=
978  setsockopt (sock,
979  IPPROTO_IPV6,
980  IPV6_RECVPKTINFO,
981  &on,
982  sizeof (on)))
983  {
985  "setsockopt");
986  }
987  }
988  {
989  struct sockaddr_in6 sa = {
990  .sin6_family = AF_INET6,
991  .sin6_port = htons ((uint16_t) nport)
992  };
993 
994  if (0 !=
995  bind (sock,
996  (const struct sockaddr *) &sa,
997  sizeof (sa)))
998  {
1000  "socket");
1001  GNUNET_break (0 ==
1002  close (sock));
1003  GNUNET_free (plugin->port);
1004  GNUNET_free (plugin);
1005  return NULL;
1006  }
1007  }
1008  break;
1009  }
1011  GNUNET_NO);
1015  plugin->sock,
1016  &read_cb,
1017  plugin);
1018  env->network_size_cb (env->cls,
1020  log (nse) / log (2),
1021  -1.0 /* stddev */);
1023  plugin);
1024  api = GNUNET_new (struct GNUNET_DHTU_PluginFunctions);
1025  api->cls = plugin;
1026  api->sign = &ip_sign;
1027  api->verify = &ip_verify;
1028  api->try_connect = &ip_try_connect;
1029  api->hold = &ip_hold;
1030  api->drop = &ip_drop;
1031  api->send = &ip_send;
1032  return api;
1033 }
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static struct in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
static struct GNUNET_NSE_Handle * nse
Network size estimation handle.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
void GNUNET_log_config_invalid(enum GNUNET_ErrorType kind, const char *section, const char *option, const char *required)
Log error message about invalid configuration option value.
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
@ GNUNET_ERROR_TYPE_ERROR
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_box_native(int fd)
Box a native socket (and check that it is a socket).
Definition: network.c:636
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
#define GNUNET_TIME_UNIT_ZERO_ABS
Absolute time zero.
static ssize_t ip_sign(void *cls, const struct GNUNET_DHTU_PrivateKey *pk, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, void **sig)
Use our private key to sign a message.
static void ip_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.
static void ip_try_connect(void *cls, const char *address)
Request creation of a session with a peer at the given address.
static enum GNUNET_GenericReturnValue ip_verify(void *cls, const struct GNUNET_DHTU_PublicKey *pk, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, const void *sig, size_t sig_size)
Verify signature in sig over purpose.
static void ip_drop(struct GNUNET_DHTU_PreferenceHandle *ph)
Do no long request underlay to keep the connection alive.
static struct GNUNET_DHTU_PreferenceHandle * ip_hold(void *cls, struct GNUNET_DHTU_Target *target)
Request underlay to keep the connection to target alive if possible.
The datastore service will pass a pointer to a struct of this type as the first and only argument to ...
void * cls
Closure to use for callbacks.
struct returned by the initialization function of the plugin
void(* try_connect)(void *cls, const char *address)
Request creation of a session with a peer at the given address.
struct GNUNET_DHTU_PreferenceHandle *(* hold)(void *cls, struct GNUNET_DHTU_Target *target)
Request underlay to keep the connection to target alive if possible.
enum GNUNET_GenericReturnValue(* verify)(void *cls, const struct GNUNET_DHTU_PublicKey *pk, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, const void *sig, size_t sig_size)
Verify signature in sig over purpose.
void * cls
Closure to pass to all plugin functions.
ssize_t(* sign)(void *cls, const struct GNUNET_DHTU_PrivateKey *pk, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, void **sig)
Use our private key to sign a message.
void(* drop)(struct GNUNET_DHTU_PreferenceHandle *ph)
Do no long 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.

References GNUNET_DHTU_PluginEnvironment::cls, GNUNET_DHTU_PluginFunctions::cls, GNUNET_DHTU_PluginFunctions::drop, Plugin::dsts, dummy, env, Plugin::env, GNUNET_break, GNUNET_CONFIGURATION_get_value_number(), GNUNET_CONFIGURATION_get_value_string(), GNUNET_CONTAINER_multihashmap_create(), GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log_config_invalid(), GNUNET_log_config_missing(), GNUNET_log_strerror, GNUNET_NETWORK_socket_box_native(), GNUNET_new, GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_add_read_net(), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_DHTU_PluginFunctions::hold, ip_drop(), ip_hold(), ip_send(), ip_sign(), ip_try_connect(), ip_verify(), nse, plugin, Plugin::port, port, read_cb(), Plugin::read_task, scan(), Plugin::scan_task, GNUNET_DHTU_PluginFunctions::send, GNUNET_DHTU_PluginFunctions::sign, Plugin::sock, GNUNET_DHTU_PluginFunctions::try_connect, and GNUNET_DHTU_PluginFunctions::verify.

Here is the call graph for this function:

◆ libgnunet_plugin_dhtu_ip_done()

void* libgnunet_plugin_dhtu_ip_done ( void *  cls)

Exit point from the plugin.

Parameters
clsclosure (our struct Plugin)
Returns
NULL

Definition at line 1043 of file plugin_dhtu_ip.c.

1044 {
1045  struct GNUNET_DHTU_PluginFunctions *api = cls;
1046  struct Plugin *plugin = api->cls;
1047  struct GNUNET_DHTU_Source *src;
1048  struct GNUNET_DHTU_Target *dst;
1049 
1050  while (NULL != (dst = plugin->dst_head))
1051  {
1052  plugin->env->disconnect_cb (dst->app_ctx);
1053  GNUNET_assert (NULL == dst->ph_head);
1055  plugin->dst_tail,
1056  dst);
1057  GNUNET_free (dst);
1058  }
1059  while (NULL != (src = plugin->src_head))
1060  {
1061  plugin->env->address_del_cb (src->app_ctx);
1063  plugin->src_tail,
1064  src);
1065  GNUNET_free (src->address);
1066  GNUNET_free (src);
1067  }
1070  GNUNET_break (0 ==
1072  GNUNET_free (plugin->port);
1073  GNUNET_free (plugin);
1074  GNUNET_free (api);
1075  return NULL;
1076 }
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
int GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:560
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:972
void * cls
Closure for all of the callbacks.
struct GNUNET_BLOCK_PluginFunctions * api
Plugin API.
Definition: block.c:47

References GNUNET_DHTU_Source::address, Plugin::api, GNUNET_DHTU_Source::app_ctx, GNUNET_DHTU_Target::app_ctx, GNUNET_BLOCK_PluginFunctions::cls, GNUNET_DHTU_PluginFunctions::cls, Plugin::dst_head, Plugin::dst_tail, Plugin::dsts, Plugin::env, GNUNET_assert, GNUNET_break, GNUNET_CONTAINER_DLL_remove, GNUNET_CONTAINER_multihashmap_destroy(), GNUNET_free, GNUNET_NETWORK_socket_close(), GNUNET_SCHEDULER_cancel(), GNUNET_DHTU_Target::ph_head, plugin, Plugin::port, Plugin::scan_task, Plugin::sock, Plugin::src_head, and Plugin::src_tail.

Here is the call graph for this function: