GNUnet  0.11.x
Data Structures | Macros | Functions | Variables
gnunet-service-nat_externalip.c File Reference

Code to figure out what our external IPv4 address(es) might be (external IPv4s are what is seen on the rest of the Internet). More...

#include "platform.h"
#include <math.h>
#include "gnunet_util_lib.h"
#include "gnunet_protocols.h"
#include "gnunet_signatures.h"
#include "gnunet_statistics_service.h"
#include "gnunet_resolver_service.h"
#include "gnunet_nat_service.h"
#include "gnunet-service-nat.h"
#include "gnunet-service-nat_externalip.h"
#include "gnunet-service-nat_stun.h"
#include "gnunet-service-nat_mini.h"
#include "gnunet-service-nat_helper.h"
#include "nat.h"
#include <gcrypt.h>
Include dependency graph for gnunet-service-nat_externalip.c:

Go to the source code of this file.

Data Structures

struct  GN_ExternalIPMonitor
 Handle to monitor for external IP changes. More...
 

Macros

#define EXTERN_IP_RETRY_TIMEOUT
 How long do we wait until we re-try running external-ip if the command failed to terminate nicely? More...
 
#define EXTERN_IP_RETRY_FAILURE
 How long do we wait until we re-try running external-ip if the command failed (but terminated)? More...
 
#define EXTERN_IP_RETRY_SUCCESS
 How long do we wait until we re-try running external-ip if the command succeeded? More...
 

Functions

static void notify_monitors_external_ipv4_change (int add, const struct in_addr *v4)
 Tell relevant clients about a change in our external IPv4 address. More...
 
static void run_external_ip (void *cls)
 Task used to run external-ip to get our external IPv4 address and pass it to NATed clients if possible. More...
 
static void handle_external_ip (void *cls, const struct in_addr *addr, enum GNUNET_NAT_StatusCode result)
 We learn our current external IP address. More...
 
void GN_nat_status_changed (int have_nat)
 We have changed our opinion about being NATed in the first place. More...
 
struct GN_ExternalIPMonitorGN_external_ipv4_monitor_start (GN_NotifyExternalIPv4Change cb, void *cb_cls)
 Start monitoring external IPv4 addresses. More...
 
void GN_external_ipv4_monitor_stop (struct GN_ExternalIPMonitor *mon)
 Stop calling monitor. More...
 

Variables

static struct GN_ExternalIPMonitormon_head
 List of monitors, kept in DLL. More...
 
static struct GN_ExternalIPMonitormon_tail
 List of monitors, kept in DLL. More...
 
static struct GNUNET_SCHEDULER_Taskprobe_external_ip_task
 Task run to obtain our external IP (if enable_upnp is set and if we find we have a NATed IP address). More...
 
static struct GNUNET_NAT_ExternalHandleprobe_external_ip_op
 Handle to our operation to run external-ip. More...
 
static struct in_addr mini_external_ipv4
 What is our external IP address as claimed by external-ip? 0 for unknown. More...
 

Detailed Description

Code to figure out what our external IPv4 address(es) might be (external IPv4s are what is seen on the rest of the Internet).

This can be implemented using different methods, and we allow the main service to be notified about changes to what we believe is our external IPv4 address.

Note that this is explicitly only about NATed systems; if one of our network interfaces has a global IP address this does not count as "external".

Functions for monitoring external IPv4 addresses

Author
Christian Grothoff

Definition in file gnunet-service-nat_externalip.c.

Macro Definition Documentation

◆ EXTERN_IP_RETRY_TIMEOUT

#define EXTERN_IP_RETRY_TIMEOUT
Value:
#define GNUNET_TIME_UNIT_MINUTES
One minute.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
Definition: time.c:311

How long do we wait until we re-try running external-ip if the command failed to terminate nicely?

Definition at line 57 of file gnunet-service-nat_externalip.c.

◆ EXTERN_IP_RETRY_FAILURE

#define EXTERN_IP_RETRY_FAILURE
Value:

How long do we wait until we re-try running external-ip if the command failed (but terminated)?

Definition at line 64 of file gnunet-service-nat_externalip.c.

◆ EXTERN_IP_RETRY_SUCCESS

#define EXTERN_IP_RETRY_SUCCESS
Value:

How long do we wait until we re-try running external-ip if the command succeeded?

Definition at line 71 of file gnunet-service-nat_externalip.c.

Function Documentation

◆ notify_monitors_external_ipv4_change()

static void notify_monitors_external_ipv4_change ( int  add,
const struct in_addr *  v4 
)
static

Tell relevant clients about a change in our external IPv4 address.

Parameters
addGNUNET_YES to add, GNUNET_NO to remove
v4the external address that changed

Definition at line 138 of file gnunet-service-nat_externalip.c.

140 {
141  for (struct GN_ExternalIPMonitor *mon = mon_head;
142  NULL != mon;
143  mon = mon->next)
144  mon->cb (mon->cb_cls,
145  v4,
146  add);
147 }
static int add
Desired action is to add a record.
static struct GN_ExternalIPMonitor * mon_head
List of monitors, kept in DLL.
Handle to monitor for external IP changes.
struct GN_ExternalIPMonitor * next
Kept in DLL.

References add, mon_head, and GN_ExternalIPMonitor::next.

Referenced by handle_external_ip().

Here is the caller graph for this function:

◆ run_external_ip()

static void run_external_ip ( void *  cls)
static

Task used to run external-ip to get our external IPv4 address and pass it to NATed clients if possible.

Parameters
clsNULL

Definition at line 221 of file gnunet-service-nat_externalip.c.

222 {
226  NULL);
227  if (NULL != probe_external_ip_op)
228  {
230  probe_external_ip_op = NULL;
231  }
234  NULL);
235 }
static struct GNUNET_NAT_ExternalHandle * probe_external_ip_op
Handle to our operation to run external-ip.
static struct GNUNET_SCHEDULER_Task * probe_external_ip_task
Task run to obtain our external IP (if enable_upnp is set and if we find we have a NATed IP address).
#define EXTERN_IP_RETRY_TIMEOUT
How long do we wait until we re-try running external-ip if the command failed to terminate nicely?
static void run_external_ip(void *cls)
Task used to run external-ip to get our external IPv4 address and pass it to NATed clients if possibl...
static void handle_external_ip(void *cls, const struct in_addr *addr, enum GNUNET_NAT_StatusCode result)
We learn our current external IP address.
void GNUNET_NAT_mini_get_external_ipv4_cancel_(struct GNUNET_NAT_ExternalHandle *eh)
Cancel operation.
struct GNUNET_NAT_ExternalHandle * GNUNET_NAT_mini_get_external_ipv4_(GNUNET_NAT_IPCallback cb, void *cb_cls)
Try to get the external IPv4 address of this peer.
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

References EXTERN_IP_RETRY_TIMEOUT, GNUNET_NAT_mini_get_external_ipv4_(), GNUNET_NAT_mini_get_external_ipv4_cancel_(), GNUNET_SCHEDULER_add_delayed(), handle_external_ip(), probe_external_ip_op, and probe_external_ip_task.

Referenced by GN_nat_status_changed(), and handle_external_ip().

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

◆ handle_external_ip()

static void handle_external_ip ( void *  cls,
const struct in_addr *  addr,
enum GNUNET_NAT_StatusCode  result 
)
static

We learn our current external IP address.

If it changed, notify all of our applicable clients. Also re-schedule run_external_ip with an appropriate timeout.

Parameters
clsNULL
addrthe address, NULL on errors
resultGNUNET_NAT_ERROR_SUCCESS on success, otherwise the specific error code

Definition at line 170 of file gnunet-service-nat_externalip.c.

173 {
174  char buf[INET_ADDRSTRLEN];
175 
176  probe_external_ip_op = NULL;
179  = GNUNET_SCHEDULER_add_delayed ((NULL == addr)
183  NULL);
184  switch (result)
185  {
187  GNUNET_assert (NULL != addr);
188  if (addr->s_addr == mini_external_ipv4.s_addr)
189  return; /* not change */
191  "Our external IP is now %s\n",
192  inet_ntop (AF_INET,
193  addr,
194  buf,
195  sizeof(buf)));
196  if (0 != mini_external_ipv4.s_addr)
199  mini_external_ipv4 = *addr;
202  break;
203 
204  default:
205  if (0 != mini_external_ipv4.s_addr)
208  mini_external_ipv4.s_addr = 0;
209  break;
210  }
211 }
static int result
Global testing status.
static struct in_addr mini_external_ipv4
What is our external IP address as claimed by external-ip? 0 for unknown.
#define EXTERN_IP_RETRY_FAILURE
How long do we wait until we re-try running external-ip if the command failed (but terminated)?
static void notify_monitors_external_ipv4_change(int add, const struct in_addr *v4)
Tell relevant clients about a change in our external IPv4 address.
#define EXTERN_IP_RETRY_SUCCESS
How long do we wait until we re-try running external-ip if the command succeeded?
static char buf[2048]
#define GNUNET_log(kind,...)
@ GNUNET_YES
Definition: gnunet_common.h:97
@ GNUNET_NO
Definition: gnunet_common.h:94
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_NAT_ERROR_SUCCESS
Just the default.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:972

References buf, EXTERN_IP_RETRY_FAILURE, EXTERN_IP_RETRY_SUCCESS, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NAT_ERROR_SUCCESS, GNUNET_NO, GNUNET_SCHEDULER_add_delayed(), GNUNET_SCHEDULER_cancel(), GNUNET_YES, mini_external_ipv4, notify_monitors_external_ipv4_change(), probe_external_ip_op, probe_external_ip_task, result, and run_external_ip().

Referenced by run_external_ip().

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

◆ GN_nat_status_changed()

void GN_nat_status_changed ( int  have_nat)

We have changed our opinion about being NATed in the first place.

Adapt our probing.

Parameters
have_natGNUNET_YES if we believe we are behind NAT

Definition at line 245 of file gnunet-service-nat_externalip.c.

246 {
247  if (GNUNET_YES != enable_upnp)
248  return;
249  if ((GNUNET_YES == have_nat) &&
250  (NULL == probe_external_ip_task) &&
251  (NULL == probe_external_ip_op))
252  {
255  NULL);
256  return;
257  }
258  if (GNUNET_NO == have_nat)
259  {
260  if (NULL != probe_external_ip_task)
261  {
263  probe_external_ip_task = NULL;
264  }
265  if (NULL != probe_external_ip_op)
266  {
268  probe_external_ip_op = NULL;
269  }
270  }
271 }
int enable_upnp
Is UPnP enabled? GNUNET_YES if enabled, GNUNET_NO if disabled, GNUNET_SYSERR if configuration enabled...
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

References enable_upnp, GNUNET_NAT_mini_get_external_ipv4_cancel_(), GNUNET_NO, GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_cancel(), GNUNET_YES, probe_external_ip_op, probe_external_ip_task, and run_external_ip().

Referenced by run_scan(), and shutdown_task().

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

◆ GN_external_ipv4_monitor_start()

struct GN_ExternalIPMonitor* GN_external_ipv4_monitor_start ( GN_NotifyExternalIPv4Change  cb,
void *  cb_cls 
)

Start monitoring external IPv4 addresses.

Parameters
cbfunction to call on changes
cb_clsclosure for cb
Returns
handle to cancel

Definition at line 282 of file gnunet-service-nat_externalip.c.

284 {
285  struct GN_ExternalIPMonitor *mon;
286 
287  mon = GNUNET_new (struct GN_ExternalIPMonitor);
288  mon->cb = cb;
289  mon->cb_cls = cb_cls;
291  mon_tail,
292  mon);
293  if (0 != mini_external_ipv4.s_addr)
294  cb (cb_cls,
296  GNUNET_YES);
297  return mon;
298 }
static struct GN_ExternalIPMonitor * mon_tail
List of monitors, kept in DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
GN_NotifyExternalIPv4Change cb
Function to call when we believe our external IPv4 address changed.

References GN_ExternalIPMonitor::cb, GN_ExternalIPMonitor::cb_cls, GNUNET_CONTAINER_DLL_insert, GNUNET_new, GNUNET_YES, mini_external_ipv4, mon_head, and mon_tail.

Referenced by handle_register().

Here is the caller graph for this function:

◆ GN_external_ipv4_monitor_stop()

void GN_external_ipv4_monitor_stop ( struct GN_ExternalIPMonitor mon)

Stop calling monitor.

Parameters
monmonitor to call

Definition at line 307 of file gnunet-service-nat_externalip.c.

308 {
310  mon_tail,
311  mon);
312  GNUNET_free (mon);
313 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_free(ptr)
Wrapper around free.

References GNUNET_CONTAINER_DLL_remove, GNUNET_free, mon_head, and mon_tail.

Referenced by client_disconnect_cb().

Here is the caller graph for this function:

Variable Documentation

◆ mon_head

struct GN_ExternalIPMonitor* mon_head
static

◆ mon_tail

struct GN_ExternalIPMonitor* mon_tail
static

List of monitors, kept in DLL.

Definition at line 110 of file gnunet-service-nat_externalip.c.

Referenced by GN_external_ipv4_monitor_start(), and GN_external_ipv4_monitor_stop().

◆ probe_external_ip_task

struct GNUNET_SCHEDULER_Task* probe_external_ip_task
static

Task run to obtain our external IP (if enable_upnp is set and if we find we have a NATed IP address).

Definition at line 116 of file gnunet-service-nat_externalip.c.

Referenced by GN_nat_status_changed(), handle_external_ip(), and run_external_ip().

◆ probe_external_ip_op

struct GNUNET_NAT_ExternalHandle* probe_external_ip_op
static

Handle to our operation to run external-ip.

Definition at line 121 of file gnunet-service-nat_externalip.c.

Referenced by GN_nat_status_changed(), handle_external_ip(), and run_external_ip().

◆ mini_external_ipv4

struct in_addr mini_external_ipv4
static

What is our external IP address as claimed by external-ip? 0 for unknown.

Definition at line 121 of file gnunet-service-nat_externalip.c.

Referenced by GN_external_ipv4_monitor_start(), and handle_external_ip().