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 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

◆ 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 240 of file plugin_dhtu_ip.c.

243 {
244  struct GNUNET_DHTU_Target *dst;
245 
246  if (MAX_DESTS >
248  {
249  struct GNUNET_HashCode key;
250 
251  dst = NULL;
252  for (struct GNUNET_DHTU_Target *pos = plugin->dst_head;
253  NULL != pos;
254  pos = pos->next)
255  {
256  /* >= here assures we remove oldest entries first */
257  if ( (NULL == dst) ||
258  (dst->ph_count >= pos->ph_count) )
259  dst = pos;
260  }
261  GNUNET_assert (NULL != dst);
262  plugin->env->disconnect_cb (dst->app_ctx);
263  GNUNET_CRYPTO_hash (&dst->addr,
264  dst->addrlen,
265  &key);
268  &key,
269  dst));
271  plugin->dst_tail,
272  dst);
273  GNUNET_assert (NULL == dst->ph_head);
274  GNUNET_free (dst);
275  }
276  dst = GNUNET_new (struct GNUNET_DHTU_Target);
277  dst->addrlen = addrlen;
278  memcpy (&dst->addr,
279  addr,
280  addrlen);
281  switch (addr->sa_family)
282  {
283  case AF_INET:
284  {
285  const struct sockaddr_in *s4 = (const struct sockaddr_in *) addr;
286 
287  GNUNET_assert (sizeof (struct sockaddr_in) == addrlen);
288  GNUNET_CRYPTO_hash (&s4->sin_addr,
289  sizeof (struct in_addr),
290  &dst->id.sha512);
291  }
292  break;
293  case AF_INET6:
294  {
295  const struct sockaddr_in6 *s6 = (const struct sockaddr_in6 *) addr;
296 
297  GNUNET_assert (sizeof (struct sockaddr_in6) == addrlen);
298  GNUNET_CRYPTO_hash (&s6->sin6_addr,
299  sizeof (struct in6_addr),
300  &dst->id.sha512);
301  }
302  break;
303  default:
304  GNUNET_break (0);
305  GNUNET_free (dst);
306  return NULL;
307  }
309  plugin->dst_tail,
310  dst);
311  plugin->env->connect_cb (plugin->env->cls,
312  dst,
313  &dst->id,
314  &dst->app_ctx);
315  return dst;
316 }
struct Plugin * plugin
The process handle to the testbed service.
struct GNUNET_HashCode key
The key used in the DHT.
@ 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.
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_Target::id, key, MAX_DESTS, GNUNET_DHTU_Target::next, plugin, and GNUNET_DHTU_HashKey::sha512.

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 330 of file plugin_dhtu_ip.c.

333 {
334  struct GNUNET_HashCode key;
335  struct GNUNET_DHTU_Target *dst;
336 
338  addrlen,
339  &key);
341  &key);
342  if (NULL == dst)
343  {
344  dst = create_target (plugin,
345  (const struct sockaddr *) addr,
346  addrlen);
349  plugin->dsts,
350  &key,
351  dst,
353  }
354  else
355  {
356  /* move to head of DLL */
358  plugin->dst_tail,
359  dst);
361  plugin->dst_tail,
362  dst);
363 
364  }
365  return dst;
366 }
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 376 of file plugin_dhtu_ip.c.

378 {
379  struct Plugin *plugin = cls;
380  char *colon;
381  const char *port;
382  char *addr;
383  struct addrinfo hints = {
384  .ai_flags = AI_NUMERICHOST | AI_NUMERICSERV
385  };
386  struct addrinfo *result = NULL;
387 
388  if (0 !=
389  strncmp (address,
390  "ip+",
391  strlen ("ip+")))
392  {
393  GNUNET_break (0);
394  return;
395  }
396  address += strlen ("ip+");
397  if (0 !=
398  strncmp (address,
399  "udp://",
400  strlen ("udp://")))
401  {
402  GNUNET_break (0);
403  return;
404  }
405  address += strlen ("udp://");
406  addr = GNUNET_strdup (address);
407  colon = strchr (addr, ':');
408  if (NULL == colon)
409  {
410  port = plugin->port;
411  }
412  else
413  {
414  *colon = '\0';
415  port = colon + 1;
416  }
417  if (0 !=
418  getaddrinfo (addr,
419  port,
420  &hints,
421  &result))
422  {
423  GNUNET_break (0);
424  GNUNET_free (addr);
425  return;
426  }
427  GNUNET_free (addr);
428  (void) find_target (plugin,
429  result->ai_addr,
430  result->ai_addrlen);
431  freeaddrinfo (result);
432 }
static uint16_t port
Port number.
Definition: gnunet-bcd.c:147
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 444 of file plugin_dhtu_ip.c.

446 {
448 
450  ph->target = target;
452  target->ph_tail,
453  ph);
454  target->ph_count++;
455  return ph;
456 }
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 466 of file plugin_dhtu_ip.c.

467 {
468  struct GNUNET_DHTU_Target *target = ph->target;
469 
471  target->ph_tail,
472  ph);
473  target->ph_count--;
474  GNUNET_free (ph);
475 }

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 494 of file plugin_dhtu_ip.c.

500 {
501  struct Plugin *plugin = cls;
502 
504  msg,
505  msg_size,
506  (const struct sockaddr *) &target->addr,
507  target->addrlen);
508  finished_cb (finished_cb_cls);
509 }
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:793
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 521 of file plugin_dhtu_ip.c.

524 {
525  struct GNUNET_DHTU_Source *src;
526 
527  src = GNUNET_new (struct GNUNET_DHTU_Source);
528  src->addrlen = addrlen;
529  memcpy (&src->addr,
530  addr,
531  addrlen);
533  switch (addr->sa_family)
534  {
535  case AF_INET:
536  {
537  const struct sockaddr_in *s4 = (const struct sockaddr_in *) addr;
538  char buf[INET_ADDRSTRLEN];
539 
540  GNUNET_assert (sizeof (struct sockaddr_in) == addrlen);
541  GNUNET_CRYPTO_hash (&s4->sin_addr,
542  sizeof (struct in_addr),
543  &src->id.sha512);
544  GNUNET_asprintf (&src->address,
545  "ip+udp://%s:%u",
546  inet_ntop (AF_INET,
547  &s4->sin_addr,
548  buf,
549  sizeof (buf)),
550  ntohs (s4->sin_port));
551  }
552  break;
553  case AF_INET6:
554  {
555  const struct sockaddr_in6 *s6 = (const struct sockaddr_in6 *) addr;
556  char buf[INET6_ADDRSTRLEN];
557 
558  GNUNET_assert (sizeof (struct sockaddr_in6) == addrlen);
559  GNUNET_CRYPTO_hash (&s6->sin6_addr,
560  sizeof (struct in6_addr),
561  &src->id.sha512);
562  GNUNET_asprintf (&src->address,
563  "ip+udp://[%s]:%u",
564  inet_ntop (AF_INET6,
565  &s6->sin6_addr,
566  buf,
567  sizeof (buf)),
568  ntohs (s6->sin6_port));
569  }
570  break;
571  default:
572  GNUNET_break (0);
573  GNUNET_free (src);
574  return NULL;
575  }
577  plugin->src_tail,
578  src);
579  plugin->env->address_add_cb (plugin->env->cls,
580  &src->id,
581  src->address,
582  src,
583  &src->app_ctx);
584  return src;
585 }
static char buf[2048]
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
struct GNUNET_HashCode sha512
Opaque handle that the underlay offers for our address to be used when sending messages to another pe...
void * app_ctx
Application context for this source.
socklen_t addrlen
Number of bytes in addr.
struct GNUNET_DHTU_HashKey id
Hash of pid, position of this peer in the DHT overlay.
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_Source::id, plugin, GNUNET_DHTU_Source::scan_generation, Plugin::scan_generation, GNUNET_DHTU_HashKey::sha512, 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 601 of file plugin_dhtu_ip.c.

608 {
609  struct Plugin *plugin = cls;
610  struct GNUNET_DHTU_Source *src;
611 
612  for (src = plugin->src_head;
613  NULL != src;
614  src = src->next)
615  {
616  if ( (addrlen == src->addrlen) &&
617  (0 == memcmp (addr,
618  &src->addr,
619  addrlen)) )
620  {
622  return GNUNET_OK;
623  }
624  }
625  (void) create_source (plugin,
626  addr,
627  addrlen);
628  return GNUNET_OK;
629 }
@ 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 638 of file plugin_dhtu_ip.c.

639 {
640  struct Plugin *plugin = cls;
641  struct GNUNET_DHTU_Source *next;
642 
645  plugin);
646  for (struct GNUNET_DHTU_Source *src = plugin->src_head;
647  NULL != src;
648  src = next)
649  {
650  next = src->next;
651  if (src->scan_generation == plugin->scan_generation)
652  continue;
654  plugin->src_tail,
655  src);
656  plugin->env->address_del_cb (src->app_ctx);
657  GNUNET_free (src->address);
658  GNUNET_free (src);
659  }
661  &scan,
662  plugin);
663 }
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 676 of file plugin_dhtu_ip.c.

679 {
680  for (struct GNUNET_DHTU_Source *src = plugin->src_head;
681  NULL != src;
682  src = src->next)
683  {
684  if ( (addrlen == src->addrlen) &&
685  (0 == memcmp (addr,
686  &src->addr,
687  addrlen)) )
688  return src;
689  }
690 
691  return create_source (plugin,
692  (const struct sockaddr *) addr,
693  addrlen);
694 }

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 703 of file plugin_dhtu_ip.c.

704 {
705  struct Plugin *plugin = cls;
706  ssize_t ret;
707  char buf[65536];
708  struct sockaddr_storage sa;
709  struct iovec iov = {
710  .iov_base = buf,
711  .iov_len = sizeof (buf)
712  };
713  char ctl[128];
714  struct msghdr mh = {
715  .msg_name = &sa,
716  .msg_namelen = sizeof (sa),
717  .msg_iov = &iov,
718  .msg_iovlen = 1,
719  .msg_control = ctl,
720  .msg_controllen = sizeof (ctl)
721  };
722 
723  ret = recvmsg (GNUNET_NETWORK_get_fd (plugin->sock),
724  &mh,
725  MSG_DONTWAIT);
726  if (ret >= 0)
727  {
728  struct GNUNET_DHTU_Target *dst = NULL;
729  struct GNUNET_DHTU_Source *src = NULL;
730  struct cmsghdr *cmsg;
731 
732  /* find IP where we received message */
733  for (cmsg = CMSG_FIRSTHDR (&mh);
734  NULL != cmsg;
735  cmsg = CMSG_NXTHDR (&mh,
736  cmsg))
737  {
738  if ( (cmsg->cmsg_level == IPPROTO_IP) &&
739  (cmsg->cmsg_type == IP_PKTINFO) )
740  {
741  if (CMSG_LEN (sizeof (struct in_pktinfo)) ==
742  cmsg->cmsg_len)
743  {
744  struct in_pktinfo pi;
745 
746  memcpy (&pi,
747  CMSG_DATA (cmsg),
748  sizeof (pi));
749  {
750  struct sockaddr_in sa = {
751  .sin_family = AF_INET,
752  .sin_addr = pi.ipi_addr
753  };
754 
755  src = find_source (plugin,
756  &sa,
757  sizeof (sa));
758  }
759  break;
760  }
761  else
762  GNUNET_break (0);
763  }
764  if ( (cmsg->cmsg_level == IPPROTO_IPV6) &&
765  (cmsg->cmsg_type == IPV6_RECVPKTINFO) )
766  {
767  if (CMSG_LEN (sizeof (struct in6_pktinfo)) ==
768  cmsg->cmsg_len)
769  {
770  struct in6_pktinfo pi;
771 
772  memcpy (&pi,
773  CMSG_DATA (cmsg),
774  sizeof (pi));
775  {
776  struct sockaddr_in6 sa = {
777  .sin6_family = AF_INET6,
778  .sin6_addr = pi.ipi6_addr,
779  .sin6_scope_id = pi.ipi6_ifindex
780  };
781 
782  src = find_source (plugin,
783  &sa,
784  sizeof (sa));
785  break;
786  }
787  }
788  else
789  GNUNET_break (0);
790  }
791  }
792  dst = find_target (plugin,
793  &sa,
794  mh.msg_namelen);
795  if ( (NULL == src) ||
796  (NULL == dst) )
797  {
798  GNUNET_break (0);
799  }
800  else
801  {
802  plugin->env->receive_cb (plugin->env->cls,
803  dst->app_ctx,
804  src->app_ctx,
805  buf,
806  ret);
807  }
808  }
811  plugin->sock,
812  &read_cb,
813  plugin);
814 }
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:1022
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 824 of file plugin_dhtu_ip.c.

825 {
827  struct GNUNET_DHTU_PluginFunctions *api;
828  struct Plugin *plugin;
829  char *port;
830  unsigned int nport;
831  int sock;
832  int af;
833  unsigned long long nse;
834 
835  if (GNUNET_OK !=
837  "DHTU-IP",
838  "NSE",
839  &nse))
840  {
842  "DHTU-IP",
843  "NSE");
844  return NULL;
845  }
846  if (GNUNET_OK !=
848  "DHTU-IP",
849  "UDP_PORT",
850  &port))
851  {
853  "DHTU-IP",
854  "UDP_PORT");
855  return NULL;
856  }
857  {
858  char dummy;
859 
860  if ( (1 != sscanf (port,
861  "%u%c",
862  &nport,
863  &dummy)) ||
864  (nport > UINT16_MAX) )
865  {
867  "DHTU-IP",
868  "UDP_PORT",
869  "must be number below 65536");
870  GNUNET_free (port);
871  return NULL;
872  }
873  }
874  plugin = GNUNET_new (struct Plugin);
875  plugin->env = env;
876  plugin->port = port;
877  af = AF_INET6;
878  sock = socket (af,
879  SOCK_DGRAM,
880  IPPROTO_UDP);
881  if (-1 == sock)
882  {
884  "socket");
887  return NULL;
888  }
889  switch (af)
890  {
891  case AF_INET:
892  {
893  int on = 1;
894 
895  if (0 !=
896  setsockopt (sock,
897  IPPROTO_IP,
898  IP_PKTINFO,
899  &on,
900  sizeof (on)))
901  {
903  "setsockopt");
904  }
905  }
906  {
907  struct sockaddr_in sa = {
908  .sin_family = AF_INET,
909  .sin_port = htons ((uint16_t) nport)
910  };
911 
912  if (0 !=
913  bind (sock,
914  (const struct sockaddr *) &sa,
915  sizeof (sa)))
916  {
918  "socket");
919  GNUNET_break (0 ==
920  close (sock));
923  return NULL;
924  }
925  }
926  break;
927  case AF_INET6:
928  {
929  int on = 1;
930 
931  if (0 !=
932  setsockopt (sock,
933  IPPROTO_IPV6,
934  IPV6_RECVPKTINFO,
935  &on,
936  sizeof (on)))
937  {
939  "setsockopt");
940  }
941  }
942  {
943  struct sockaddr_in6 sa = {
944  .sin6_family = AF_INET6,
945  .sin6_port = htons ((uint16_t) nport)
946  };
947 
948  if (0 !=
949  bind (sock,
950  (const struct sockaddr *) &sa,
951  sizeof (sa)))
952  {
954  "socket");
955  GNUNET_break (0 ==
956  close (sock));
959  return NULL;
960  }
961  }
962  break;
963  }
965  GNUNET_NO);
969  plugin->sock,
970  &read_cb,
971  plugin);
972  env->network_size_cb (env->cls,
974  log (nse) / log (2),
975  -1.0 /* stddev */);
977  plugin);
979  api->cls = plugin;
980  api->try_connect = &ip_try_connect;
981  api->hold = &ip_hold;
982  api->drop = &ip_drop;
983  api->send = &ip_send;
984  return api;
985 }
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.
@ GNUNET_NO
Definition: gnunet_common.h:94
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:583
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 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 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.
void * cls
Closure to pass to all plugin functions.
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_try_connect(), nse, plugin, Plugin::port, port, read_cb(), Plugin::read_task, scan(), Plugin::scan_task, GNUNET_DHTU_PluginFunctions::send, Plugin::sock, and GNUNET_DHTU_PluginFunctions::try_connect.

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 995 of file plugin_dhtu_ip.c.

996 {
997  struct GNUNET_DHTU_PluginFunctions *api = cls;
998  struct Plugin *plugin = api->cls;
999  struct GNUNET_DHTU_Source *src;
1000  struct GNUNET_DHTU_Target *dst;
1001 
1002  while (NULL != (dst = plugin->dst_head))
1003  {
1004  plugin->env->disconnect_cb (dst->app_ctx);
1005  GNUNET_assert (NULL == dst->ph_head);
1007  plugin->dst_tail,
1008  dst);
1009  GNUNET_free (dst);
1010  }
1011  while (NULL != (src = plugin->src_head))
1012  {
1013  plugin->env->address_del_cb (src->app_ctx);
1015  plugin->src_tail,
1016  src);
1017  GNUNET_free (src->address);
1018  GNUNET_free (src);
1019  }
1022  GNUNET_break (0 ==
1024  GNUNET_free (plugin->port);
1025  GNUNET_free (plugin);
1026  GNUNET_free (api);
1027  return NULL;
1028 }
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:507
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: