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

functions for interaction with miniupnp; tested with miniupnpc 1.5 More...

#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_nat_service.h"
#include "gnunet-service-nat_mini.h"
#include "nat.h"
Include dependency graph for gnunet-service-nat_mini.c:

Go to the source code of this file.

Data Structures

struct  GNUNET_NAT_ExternalHandle
 Opaque handle to cancel "GNUNET_NAT_mini_get_external_ipv4" operation. More...
 
struct  GNUNET_NAT_MiniHandle
 Handle to a mapping created with upnpc. More...
 

Macros

#define LOG(kind, ...)   GNUNET_log_from (kind, "nat", __VA_ARGS__)
 
#define MAP_TIMEOUT   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15)
 How long do we give upnpc to create a mapping? More...
 
#define UNMAP_TIMEOUT   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1)
 How long do we give upnpc to remove a mapping? More...
 
#define MAP_REFRESH_FREQ   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
 How often do we check for changes in the mapping? More...
 

Functions

static void read_external_ipv4 (void *cls)
 Read the output of external-ip into buf. More...
 
static void signal_external_ip_error (void *cls)
 (Asynchronously) signal error invoking external-ip to client. More...
 
struct GNUNET_NAT_ExternalHandleGNUNET_NAT_mini_get_external_ipv4_ (GNUNET_NAT_IPCallback cb, void *cb_cls)
 Try to get the external IPv4 address of this peer. More...
 
void GNUNET_NAT_mini_get_external_ipv4_cancel_ (struct GNUNET_NAT_ExternalHandle *eh)
 Cancel operation. More...
 
static void do_refresh (void *cls)
 Run "upnpc -l" to find out if our mapping changed. More...
 
static void process_map_output (void *cls, const char *line)
 Process the output from the "upnpc -r" command. More...
 
static void run_upnpc_r (struct GNUNET_NAT_MiniHandle *mini)
 Run "upnpc -r" to map our internal port. More...
 
static void process_refresh_output (void *cls, const char *line)
 Process the output from "upnpc -l" to see if our external mapping changed. More...
 
struct GNUNET_NAT_MiniHandleGNUNET_NAT_mini_map_start (uint16_t port, int is_tcp, GNUNET_NAT_MiniAddressCallback ac, void *ac_cls)
 Start mapping the given port using (mini)upnpc. More...
 
static void process_unmap_output (void *cls, const char *line)
 Process output from our 'unmap' command. More...
 
void GNUNET_NAT_mini_map_stop (struct GNUNET_NAT_MiniHandle *mini)
 Remove a mapping created with (mini)upnpc. More...
 

Detailed Description

functions for interaction with miniupnp; tested with miniupnpc 1.5

Author
Christian Grothoff

Definition in file gnunet-service-nat_mini.c.

Macro Definition Documentation

◆ LOG

#define LOG (   kind,
  ... 
)    GNUNET_log_from (kind, "nat", __VA_ARGS__)

◆ MAP_TIMEOUT

How long do we give upnpc to create a mapping?

Definition at line 37 of file gnunet-service-nat_mini.c.

Referenced by do_refresh(), and run_upnpc_r().

◆ UNMAP_TIMEOUT

How long do we give upnpc to remove a mapping?

Definition at line 42 of file gnunet-service-nat_mini.c.

Referenced by GNUNET_NAT_mini_map_stop().

◆ MAP_REFRESH_FREQ

#define MAP_REFRESH_FREQ   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)

How often do we check for changes in the mapping?

Definition at line 48 of file gnunet-service-nat_mini.c.

Referenced by do_refresh(), GNUNET_NAT_mini_map_start(), and process_map_output().

Function Documentation

◆ read_external_ipv4()

static void read_external_ipv4 ( void *  cls)
static

Read the output of external-ip into buf.

When complete, parse the address and call our callback.

Parameters
clsthe struct GNUNET_NAT_ExternalHandle

Definition at line 113 of file gnunet-service-nat_mini.c.

References GNUNET_NAT_ExternalHandle::buf, GNUNET_NAT_ExternalHandle::cb, GNUNET_NAT_ExternalHandle::cb_cls, GNUNET_DISK_file_read(), GNUNET_NAT_ERROR_EXTERNAL_IP_ADDRESS_INVALID, GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_OUTPUT_INVALID, GNUNET_NAT_ERROR_SUCCESS, GNUNET_NAT_mini_get_external_ipv4_cancel_(), GNUNET_SCHEDULER_add_read_file(), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_NAT_ExternalHandle::off, GNUNET_NAT_ExternalHandle::r, GNUNET_NAT_ExternalHandle::ret, and GNUNET_NAT_ExternalHandle::task.

Referenced by GNUNET_NAT_mini_get_external_ipv4_().

114 {
115  struct GNUNET_NAT_ExternalHandle *eh = cls;
116  ssize_t ret;
117  struct in_addr addr;
118 
119  eh->task = NULL;
120  ret = GNUNET_DISK_file_read (eh->r,
121  &eh->buf[eh->off],
122  sizeof(eh->buf) - eh->off);
123  if (ret > 0)
124  {
125  /* try to read more */
126  eh->off += ret;
128  eh->r,
130  eh);
131  return;
132  }
134  if ((eh->off > 7) && (eh->buf[eh->off - 1] == '\n'))
135  {
136  eh->buf[eh->off - 1] = '\0';
137  if (1 == inet_pton (AF_INET, eh->buf, &addr))
138  {
139  if (0 == addr.s_addr)
140  eh->ret =
142  else
144  }
145  }
146  eh->cb (eh->cb_cls,
147  (GNUNET_NAT_ERROR_SUCCESS == eh->ret) ? &addr : NULL,
148  eh->ret);
150 }
Opaque handle to cancel "GNUNET_NAT_mini_get_external_ipv4" operation.
ssize_t GNUNET_DISK_file_read(const struct GNUNET_DISK_FileHandle *h, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition: disk.c:732
enum GNUNET_NAT_StatusCode ret
Error code for better debugging and user feedback.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_read_file(struct GNUNET_TIME_Relative delay, const struct GNUNET_DISK_FileHandle *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:1636
struct GNUNET_SCHEDULER_Task * task
Read task.
GNUNET_NAT_IPCallback cb
Function to call with the result.
`external-ip' command output invalid
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
size_t off
Number of bytes in buf that are valid.
static void read_external_ipv4(void *cls)
Read the output of external-ip into buf.
const struct GNUNET_DISK_FileHandle * r
Read handle of opipe.
"no valid address was returned by `external-ip'"
char buf[17]
Destination of our read operation (output of 'external-ip').
void GNUNET_NAT_mini_get_external_ipv4_cancel_(struct GNUNET_NAT_ExternalHandle *eh)
Cancel operation.
void * cb_cls
Closure for cb.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ signal_external_ip_error()

static void signal_external_ip_error ( void *  cls)
static

(Asynchronously) signal error invoking external-ip to client.

Parameters
clsthe struct GNUNET_NAT_ExternalHandle (freed)

Definition at line 159 of file gnunet-service-nat_mini.c.

References GNUNET_NAT_ExternalHandle::cb, GNUNET_NAT_ExternalHandle::cb_cls, GNUNET_free, GNUNET_NAT_ExternalHandle::ret, and GNUNET_NAT_ExternalHandle::task.

Referenced by GNUNET_NAT_mini_get_external_ipv4_().

160 {
161  struct GNUNET_NAT_ExternalHandle *eh = cls;
162 
163  eh->task = NULL;
164  eh->cb (eh->cb_cls, NULL, eh->ret);
165  GNUNET_free (eh);
166 }
Opaque handle to cancel "GNUNET_NAT_mini_get_external_ipv4" operation.
enum GNUNET_NAT_StatusCode ret
Error code for better debugging and user feedback.
struct GNUNET_SCHEDULER_Task * task
Read task.
GNUNET_NAT_IPCallback cb
Function to call with the result.
void * cb_cls
Closure for cb.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the caller graph for this function:

◆ GNUNET_NAT_mini_get_external_ipv4_()

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.

Parameters
cbfunction to call with result
cb_clsclosure for cb
Returns
handle for cancellation (can only be used until cb is called), never NULL

Definition at line 177 of file gnunet-service-nat_mini.c.

References _, GNUNET_NAT_ExternalHandle::cb, GNUNET_NAT_ExternalHandle::cb_cls, GNUNET_NAT_ExternalHandle::eip, GNUNET_DISK_pipe(), GNUNET_DISK_pipe_close(), GNUNET_DISK_pipe_close_end(), GNUNET_DISK_PIPE_END_READ, GNUNET_DISK_PIPE_END_WRITE, GNUNET_DISK_pipe_handle(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_INFO, GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_FAILED, GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_NOT_FOUND, GNUNET_NAT_ERROR_IPC_FAILURE, GNUNET_NAT_ERROR_SUCCESS, GNUNET_new, GNUNET_NO, GNUNET_OS_check_helper_binary(), GNUNET_OS_start_process(), GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_add_read_file(), GNUNET_SYSERR, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, LOG, GNUNET_NAT_ExternalHandle::opipe, GNUNET_NAT_ExternalHandle::r, read_external_ipv4(), GNUNET_NAT_ExternalHandle::ret, signal_external_ip_error(), and GNUNET_NAT_ExternalHandle::task.

Referenced by run_external_ip().

178 {
179  struct GNUNET_NAT_ExternalHandle *eh;
180 
182  eh->cb = cb;
183  eh->cb_cls = cb_cls;
185  if (GNUNET_SYSERR ==
186  GNUNET_OS_check_helper_binary ("external-ip", GNUNET_NO, NULL))
187  {
188  LOG (GNUNET_ERROR_TYPE_INFO, _ ("`external-ip' command not found\n"));
191  return eh;
192  }
194  "Running `external-ip' to determine our external IP\n");
196  if (NULL == eh->opipe)
197  {
200  return eh;
201  }
203  0,
204  NULL,
205  eh->opipe,
206  NULL,
207  "external-ip",
208  "external-ip",
209  NULL);
210  if (NULL == eh->eip)
211  {
215  return eh;
216  }
220  eh->r,
222  eh);
223  return eh;
224 }
Opaque handle to cancel "GNUNET_NAT_mini_get_external_ipv4" operation.
enum GNUNET_NAT_StatusCode ret
Error code for better debugging and user feedback.
struct GNUNET_OS_Process * GNUNET_OS_start_process(int pipe_control, enum GNUNET_OS_InheritStdioFlags std_inheritance, struct GNUNET_DISK_PipeHandle *pipe_stdin, struct GNUNET_DISK_PipeHandle *pipe_stdout, struct GNUNET_DISK_PipeHandle *pipe_stderr, const char *filename,...)
Start a process.
Definition: os_priority.c:687
#define LOG(kind,...)
struct GNUNET_OS_Process * eip
Handle to external-ip process.
#define GNUNET_NO
Definition: gnunet_common.h:78
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_read_file(struct GNUNET_TIME_Relative delay, const struct GNUNET_DISK_FileHandle *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:1636
int GNUNET_OS_check_helper_binary(const char *binary, int check_suid, const char *params)
Check whether an executable exists and possibly if the suid bit is set on the file.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
struct GNUNET_SCHEDULER_Task * task
Read task.
GNUNET_NAT_IPCallback cb
Function to call with the result.
const struct GNUNET_DISK_FileHandle * GNUNET_DISK_pipe_handle(const struct GNUNET_DISK_PipeHandle *p, enum GNUNET_DISK_PipeEnd n)
Get the handle to a particular pipe end.
Definition: disk.c:1753
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
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:1280
static void signal_external_ip_error(void *cls)
(Asynchronously) signal error invoking external-ip to client.
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
The writing-end of a pipe.
The reading-end of a pipe.
struct GNUNET_DISK_PipeHandle * GNUNET_DISK_pipe(int blocking_read, int blocking_write, int inherit_read, int inherit_write)
Creates an interprocess channel.
Definition: disk.c:1526
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
`external-ip' command not found
static void read_external_ipv4(void *cls)
Read the output of external-ip into buf.
const struct GNUNET_DISK_FileHandle * r
Read handle of opipe.
int GNUNET_DISK_pipe_close(struct GNUNET_DISK_PipeHandle *p)
Closes an interprocess channel.
Definition: disk.c:1715
int GNUNET_DISK_pipe_close_end(struct GNUNET_DISK_PipeHandle *p, enum GNUNET_DISK_PipeEnd end)
Closes one half of an interprocess channel.
Definition: disk.c:1643
struct GNUNET_DISK_PipeHandle * opipe
Handle to stdout pipe of external-ip.
#define GNUNET_YES
Definition: gnunet_common.h:77
Failed to run external-ip command.
void * cb_cls
Closure for cb.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_NAT_mini_get_external_ipv4_cancel_()

void GNUNET_NAT_mini_get_external_ipv4_cancel_ ( struct GNUNET_NAT_ExternalHandle eh)

Cancel operation.

Parameters
ehoperation to cancel

Definition at line 233 of file gnunet-service-nat_mini.c.

References GNUNET_NAT_ExternalHandle::eip, GNUNET_break, GNUNET_DISK_pipe_close(), GNUNET_free, GNUNET_OK, GNUNET_OS_process_destroy(), GNUNET_OS_process_kill(), GNUNET_OS_process_wait(), GNUNET_SCHEDULER_cancel(), GNUNET_NAT_ExternalHandle::opipe, and GNUNET_NAT_ExternalHandle::task.

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

234 {
235  if (NULL != eh->eip)
236  {
237  (void) GNUNET_OS_process_kill (eh->eip, SIGKILL);
240  }
241  if (NULL != eh->opipe)
242  {
244  eh->opipe = NULL;
245  }
246  if (NULL != eh->task)
247  {
249  eh->task = NULL;
250  }
251  GNUNET_free (eh);
252 }
void GNUNET_OS_process_destroy(struct GNUNET_OS_Process *proc)
Cleans up process structure contents (OS-dependent) and deallocates it.
Definition: os_priority.c:287
struct GNUNET_OS_Process * eip
Handle to external-ip process.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
struct GNUNET_SCHEDULER_Task * task
Read task.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
int GNUNET_DISK_pipe_close(struct GNUNET_DISK_PipeHandle *p)
Closes an interprocess channel.
Definition: disk.c:1715
int GNUNET_OS_process_wait(struct GNUNET_OS_Process *proc)
Wait for a process to terminate.
Definition: os_priority.c:1000
struct GNUNET_DISK_PipeHandle * opipe
Handle to stdout pipe of external-ip.
#define GNUNET_free(ptr)
Wrapper around free.
int GNUNET_OS_process_kill(struct GNUNET_OS_Process *proc, int sig)
Sends a signal to the process.
Definition: os_priority.c:225
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966
Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_refresh()

static void do_refresh ( void *  cls)
static

Run "upnpc -l" to find out if our mapping changed.

Parameters
clsthe struct GNUNET_NAT_MiniHandle
clsthe 'struct GNUNET_NAT_MiniHandle'

Definition at line 481 of file gnunet-service-nat_mini.c.

References ac, GNUNET_NAT_MiniHandle::ac, GNUNET_NAT_MiniHandle::ac_cls, GNUNET_NAT_MiniHandle::found, GNUNET_ERROR_TYPE_DEBUG, GNUNET_NAT_ERROR_UPNPC_TIMEOUT, GNUNET_NO, GNUNET_OS_command_run(), GNUNET_OS_command_stop(), GNUNET_SCHEDULER_add_delayed(), GNUNET_SYSERR, GNUNET_YES, LOG, GNUNET_NAT_MiniHandle::map_cmd, MAP_REFRESH_FREQ, MAP_TIMEOUT, process_refresh_output(), GNUNET_NAT_MiniHandle::refresh_cmd, and GNUNET_NAT_MiniHandle::refresh_task.

Referenced by GNUNET_NAT_mini_map_start(), and process_map_output().

482 {
483  struct GNUNET_NAT_MiniHandle *mini = cls;
484  int ac;
485 
486  mini->refresh_task =
489  "Running `upnpc' to check if our mapping still exists\n");
490  mini->found = GNUNET_NO;
491  ac = GNUNET_NO;
492  if (NULL != mini->map_cmd)
493  {
494  /* took way too long, abort it! */
496  mini->map_cmd = NULL;
497  ac = GNUNET_YES;
498  }
499  if (NULL != mini->refresh_cmd)
500  {
501  /* took way too long, abort it! */
503  mini->refresh_cmd = NULL;
504  ac = GNUNET_YES;
505  }
507  mini,
508  MAP_TIMEOUT,
509  "upnpc",
510  "upnpc",
511  "-l",
512  NULL);
513  if (GNUNET_YES == ac)
514  mini->ac (mini->ac_cls,
516  NULL,
517  0,
519 }
#define MAP_REFRESH_FREQ
How often do we check for changes in the mapping?
struct GNUNET_OS_CommandHandle * refresh_cmd
Command used to refresh our map information.
Handle to a mapping created with upnpc.
static void do_refresh(void *cls)
Run "upnpc -l" to find out if our mapping changed.
#define LOG(kind,...)
`upnpc' command took too long, process killed
#define GNUNET_NO
Definition: gnunet_common.h:78
#define MAP_TIMEOUT
How long do we give upnpc to create a mapping?
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:1253
struct GNUNET_SCHEDULER_Task * refresh_task
We check the mapping periodically to see if it still works.
void * ac_cls
Closure for ac.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static struct GNUNET_MQ_Envelope * ac
Handle to current GNUNET_PEERINFO_add_peer() operation.
struct GNUNET_OS_CommandHandle * GNUNET_OS_command_run(GNUNET_OS_LineProcessor proc, void *proc_cls, struct GNUNET_TIME_Relative timeout, const char *binary,...)
Run the given command line and call the given function for each line of the output.
Definition: os_priority.c:1161
static void process_refresh_output(void *cls, const char *line)
Process the output from "upnpc -l" to see if our external mapping changed.
struct GNUNET_OS_CommandHandle * map_cmd
Command used to install the map.
int found
Did we find our mapping during refresh scan?
void GNUNET_OS_command_stop(struct GNUNET_OS_CommandHandle *cmd)
Stop/kill a command.
Definition: os_priority.c:1076
#define GNUNET_YES
Definition: gnunet_common.h:77
GNUNET_NAT_MiniAddressCallback ac
Function to call on mapping changes.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_map_output()

static void process_map_output ( void *  cls,
const char *  line 
)
static

Process the output from the "upnpc -r" command.

Process the output from the 'upnpc -r' command.

Parameters
clsthe struct GNUNET_NAT_MiniHandle
lineline of output, NULL at the end

Definition at line 529 of file gnunet-service-nat_mini.c.

References GNUNET_NAT_MiniHandle::ac, GNUNET_NAT_MiniHandle::ac_cls, GNUNET_NAT_MiniHandle::current_addr, GNUNET_NAT_MiniHandle::did_map, do_refresh(), GNUNET_free, GNUNET_NAT_ERROR_SUCCESS, GNUNET_NAT_ERROR_UPNPC_PORTMAP_FAILED, GNUNET_OS_command_stop(), GNUNET_SCHEDULER_add_delayed(), GNUNET_strdup, GNUNET_SYSERR, GNUNET_YES, GNUNET_NAT_MiniHandle::map_cmd, MAP_REFRESH_FREQ, port, and GNUNET_NAT_MiniHandle::refresh_task.

Referenced by run_upnpc_r().

530 {
531  struct GNUNET_NAT_MiniHandle *mini = cls;
532  const char *ipaddr;
533  char *ipa;
534  const char *pstr;
535  unsigned int port;
536 
537  if (NULL == line)
538  {
540  mini->map_cmd = NULL;
541  if (GNUNET_YES != mini->did_map)
542  mini->ac (mini->ac_cls,
544  NULL,
545  0,
547  if (NULL == mini->refresh_task)
548  mini->refresh_task =
550  return;
551  }
552  /*
553  * The upnpc output we're after looks like this:
554  *
555  * "external 87.123.42.204:3000 TCP is redirected to internal 192.168.2.150:3000"
556  */if ((NULL == (ipaddr = strstr (line, " "))) ||
557  (NULL == (pstr = strstr (ipaddr, ":"))) ||
558  (1 != sscanf (pstr + 1, "%u", &port)))
559  {
560  return; /* skip line */
561  }
562  ipa = GNUNET_strdup (ipaddr + 1);
563  strstr (ipa, ":")[0] = '\0';
564  if (1 != inet_pton (AF_INET, ipa, &mini->current_addr.sin_addr))
565  {
566  GNUNET_free (ipa);
567  return; /* skip line */
568  }
569  GNUNET_free (ipa);
570 
571  mini->current_addr.sin_port = htons (port);
572  mini->current_addr.sin_family = AF_INET;
573 #if HAVE_SOCKADDR_IN_SIN_LEN
574  mini->current_addr.sin_len = sizeof(struct sockaddr_in);
575 #endif
576  mini->did_map = GNUNET_YES;
577  mini->ac (mini->ac_cls,
578  GNUNET_YES,
579  (const struct sockaddr *) &mini->current_addr,
580  sizeof(mini->current_addr),
582 }
#define MAP_REFRESH_FREQ
How often do we check for changes in the mapping?
Handle to a mapping created with upnpc.
`upnpc' command failed to establish port mapping
static void do_refresh(void *cls)
Run "upnpc -l" to find out if our mapping changed.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
int did_map
Did we succeed with creating a mapping?
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:1253
static char * line
Desired phone line (string to be converted to a hash).
struct GNUNET_SCHEDULER_Task * refresh_task
We check the mapping periodically to see if it still works.
void * ac_cls
Closure for ac.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static uint16_t port
Port number.
Definition: gnunet-bcd.c:81
struct GNUNET_OS_CommandHandle * map_cmd
Command used to install the map.
void GNUNET_OS_command_stop(struct GNUNET_OS_CommandHandle *cmd)
Stop/kill a command.
Definition: os_priority.c:1076
#define GNUNET_YES
Definition: gnunet_common.h:77
GNUNET_NAT_MiniAddressCallback ac
Function to call on mapping changes.
struct sockaddr_in current_addr
Our current external mapping (if we have one).
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ run_upnpc_r()

static void run_upnpc_r ( struct GNUNET_NAT_MiniHandle mini)
static

Run "upnpc -r" to map our internal port.

Parameters
miniour handle

Definition at line 346 of file gnunet-service-nat_mini.c.

References GNUNET_NAT_MiniHandle::ac, GNUNET_NAT_MiniHandle::ac_cls, GNUNET_NAT_ERROR_UPNPC_FAILED, GNUNET_OS_command_run(), GNUNET_snprintf(), GNUNET_SYSERR, GNUNET_NAT_MiniHandle::is_tcp, GNUNET_NAT_MiniHandle::map_cmd, MAP_TIMEOUT, GNUNET_NAT_MiniHandle::port, and process_map_output().

Referenced by GNUNET_NAT_mini_map_start(), and process_refresh_output().

347 {
348  char pstr[6];
349 
350  GNUNET_snprintf (pstr, sizeof(pstr), "%u", (unsigned int) mini->port);
352  mini,
353  MAP_TIMEOUT,
354  "upnpc",
355  "upnpc",
356  "-r",
357  pstr,
358  mini->is_tcp ? "tcp" : "udp",
359  NULL);
360  if (NULL == mini->map_cmd)
361  {
362  mini->ac (mini->ac_cls,
364  NULL,
365  0,
367  return;
368  }
369 }
int GNUNET_snprintf(char *buf, size_t size, const char *format,...)
Like snprintf, just aborts if the buffer is of insufficient size.
int is_tcp
Are we mapping TCP or UDP?
static void process_map_output(void *cls, const char *line)
Process the output from the "upnpc -r" command.
#define MAP_TIMEOUT
How long do we give upnpc to create a mapping?
void * ac_cls
Closure for ac.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
uint16_t port
Which port are we mapping?
struct GNUNET_OS_CommandHandle * GNUNET_OS_command_run(GNUNET_OS_LineProcessor proc, void *proc_cls, struct GNUNET_TIME_Relative timeout, const char *binary,...)
Run the given command line and call the given function for each line of the output.
Definition: os_priority.c:1161
struct GNUNET_OS_CommandHandle * map_cmd
Command used to install the map.
Failed to run upnpc command.
GNUNET_NAT_MiniAddressCallback ac
Function to call on mapping changes.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_refresh_output()

static void process_refresh_output ( void *  cls,
const char *  line 
)
static

Process the output from "upnpc -l" to see if our external mapping changed.

If so, do the notifications.

Parameters
clsthe struct GNUNET_NAT_MiniHandle
lineline of output, NULL at the end

Definition at line 380 of file gnunet-service-nat_mini.c.

References GNUNET_NAT_MiniHandle::ac, GNUNET_NAT_MiniHandle::ac_cls, GNUNET_NAT_MiniHandle::current_addr, GNUNET_NAT_MiniHandle::did_map, GNUNET_NAT_MiniHandle::found, GNUNET_NAT_ERROR_SUCCESS, GNUNET_NO, GNUNET_OS_command_stop(), GNUNET_snprintf(), GNUNET_YES, GNUNET_NAT_MiniHandle::is_tcp, GNUNET_NAT_MiniHandle::port, GNUNET_NAT_MiniHandle::refresh_cmd, and run_upnpc_r().

Referenced by do_refresh().

381 {
382  struct GNUNET_NAT_MiniHandle *mini = cls;
383  char pstr[9];
384  const char *s;
385  unsigned int nport;
386  struct in_addr exip;
387 
388  if (NULL == line)
389  {
391  mini->refresh_cmd = NULL;
392  if (GNUNET_NO == mini->found)
393  {
394  /* mapping disappeared, try to re-create */
395  if (GNUNET_YES == mini->did_map)
396  {
397  mini->ac (mini->ac_cls,
398  GNUNET_NO,
399  (const struct sockaddr *) &mini->current_addr,
400  sizeof(mini->current_addr),
402  mini->did_map = GNUNET_NO;
403  }
404  run_upnpc_r (mini);
405  }
406  return;
407  }
408  if (! mini->did_map)
409  return; /* never mapped, won't find our mapping anyway */
410 
411  /* we're looking for output of the form:
412  * "ExternalIPAddress = 12.134.41.124" */
413 
414  s = strstr (line, "ExternalIPAddress = ");
415  if (NULL != s)
416  {
417  s += strlen ("ExternalIPAddress = ");
418  if (1 != inet_pton (AF_INET, s, &exip))
419  return; /* skip */
420  if (exip.s_addr == mini->current_addr.sin_addr.s_addr)
421  return; /* no change */
422  /* update mapping */
423  mini->ac (mini->ac_cls,
424  GNUNET_NO,
425  (const struct sockaddr *) &mini->current_addr,
426  sizeof(mini->current_addr),
428  mini->current_addr.sin_addr = exip;
429  mini->ac (mini->ac_cls,
430  GNUNET_YES,
431  (const struct sockaddr *) &mini->current_addr,
432  sizeof(mini->current_addr),
434  return;
435  }
436  /*
437  * we're looking for output of the form:
438  *
439  * "0 TCP 3000->192.168.2.150:3000 'libminiupnpc' ''"
440  * "1 UDP 3001->192.168.2.150:3001 'libminiupnpc' ''"
441  *
442  * the pattern we look for is:
443  *
444  * "%s TCP PORT->STRING:OURPORT *" or
445  * "%s UDP PORT->STRING:OURPORT *"
446  */GNUNET_snprintf (pstr, sizeof(pstr), ":%u ", mini->port);
447  if (NULL == (s = strstr (line, "->")))
448  return; /* skip */
449  if (NULL == strstr (s, pstr))
450  return; /* skip */
451  if (1 != sscanf (line,
452  (mini->is_tcp) ? "%*u TCP %u->%*s:%*u %*s"
453  : "%*u UDP %u->%*s:%*u %*s",
454  &nport))
455  return; /* skip */
456  mini->found = GNUNET_YES;
457  if (nport == ntohs (mini->current_addr.sin_port))
458  return; /* no change */
459 
460  /* external port changed, update mapping */
461  mini->ac (mini->ac_cls,
462  GNUNET_NO,
463  (const struct sockaddr *) &mini->current_addr,
464  sizeof(mini->current_addr),
466  mini->current_addr.sin_port = htons ((uint16_t) nport);
467  mini->ac (mini->ac_cls,
468  GNUNET_YES,
469  (const struct sockaddr *) &mini->current_addr,
470  sizeof(mini->current_addr),
472 }
struct GNUNET_OS_CommandHandle * refresh_cmd
Command used to refresh our map information.
Handle to a mapping created with upnpc.
int GNUNET_snprintf(char *buf, size_t size, const char *format,...)
Like snprintf, just aborts if the buffer is of insufficient size.
int is_tcp
Are we mapping TCP or UDP?
#define GNUNET_NO
Definition: gnunet_common.h:78
int did_map
Did we succeed with creating a mapping?
static char * line
Desired phone line (string to be converted to a hash).
void * ac_cls
Closure for ac.
uint16_t port
Which port are we mapping?
int found
Did we find our mapping during refresh scan?
void GNUNET_OS_command_stop(struct GNUNET_OS_CommandHandle *cmd)
Stop/kill a command.
Definition: os_priority.c:1076
#define GNUNET_YES
Definition: gnunet_common.h:77
GNUNET_NAT_MiniAddressCallback ac
Function to call on mapping changes.
struct sockaddr_in current_addr
Our current external mapping (if we have one).
static void run_upnpc_r(struct GNUNET_NAT_MiniHandle *mini)
Run "upnpc -r" to map our internal port.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_NAT_mini_map_start()

struct GNUNET_NAT_MiniHandle* GNUNET_NAT_mini_map_start ( uint16_t  port,
int  is_tcp,
GNUNET_NAT_MiniAddressCallback  ac,
void *  ac_cls 
)

Start mapping the given port using (mini)upnpc.

This function should typically not be used directly (it is used within the general-purpose GNUNET_NAT_register() code). However, it can be used if specifically UPnP-based NAT traversal is to be used or tested.

Parameters
portport to map
is_tcpGNUNET_YES to map TCP, GNUNET_NO for UDP
acfunction to call with mapping result
ac_clsclosure for ac
Returns
NULL on error (no 'upnpc' installed)

Definition at line 599 of file gnunet-service-nat_mini.c.

References _, ac, GNUNET_NAT_MiniHandle::ac, GNUNET_NAT_MiniHandle::ac_cls, do_refresh(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_INFO, GNUNET_NAT_ERROR_UPNPC_NOT_FOUND, GNUNET_new, GNUNET_NO, GNUNET_OS_check_helper_binary(), GNUNET_SCHEDULER_add_delayed(), GNUNET_SYSERR, GNUNET_NAT_MiniHandle::is_tcp, LOG, MAP_REFRESH_FREQ, port, GNUNET_NAT_MiniHandle::port, GNUNET_NAT_MiniHandle::refresh_task, GNUNET_NAT_ExternalHandle::ret, and run_upnpc_r().

Referenced by handle_register().

603 {
604  struct GNUNET_NAT_MiniHandle *ret;
605 
606  if (GNUNET_SYSERR == GNUNET_OS_check_helper_binary ("upnpc", GNUNET_NO, NULL))
607  {
608  LOG (GNUNET_ERROR_TYPE_INFO, _ ("`upnpc' command not found\n"));
610  return NULL;
611  }
612  LOG (GNUNET_ERROR_TYPE_DEBUG, "Running `upnpc' to install mapping\n");
613  ret = GNUNET_new (struct GNUNET_NAT_MiniHandle);
614  ret->ac = ac;
615  ret->ac_cls = ac_cls;
616  ret->is_tcp = is_tcp;
617  ret->port = port;
618  ret->refresh_task =
620  run_upnpc_r (ret);
621  return ret;
622 }
#define MAP_REFRESH_FREQ
How often do we check for changes in the mapping?
Handle to a mapping created with upnpc.
static void do_refresh(void *cls)
Run "upnpc -l" to find out if our mapping changed.
#define LOG(kind,...)
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
int is_tcp
Are we mapping TCP or UDP?
#define GNUNET_NO
Definition: gnunet_common.h:78
int GNUNET_OS_check_helper_binary(const char *binary, int check_suid, const char *params)
Check whether an executable exists and possibly if the suid bit is set on the file.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
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:1253
struct GNUNET_SCHEDULER_Task * refresh_task
We check the mapping periodically to see if it still works.
void * ac_cls
Closure for ac.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
uint16_t port
Which port are we mapping?
static struct GNUNET_MQ_Envelope * ac
Handle to current GNUNET_PEERINFO_add_peer() operation.
static uint16_t port
Port number.
Definition: gnunet-bcd.c:81
GNUNET_NAT_MiniAddressCallback ac
Function to call on mapping changes.
static void run_upnpc_r(struct GNUNET_NAT_MiniHandle *mini)
Run "upnpc -r" to map our internal port.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_unmap_output()

static void process_unmap_output ( void *  cls,
const char *  line 
)
static

Process output from our 'unmap' command.

Parameters
clsthe struct GNUNET_NAT_MiniHandle
lineline of output, NULL at the end

Definition at line 632 of file gnunet-service-nat_mini.c.

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_OS_command_stop(), LOG, and GNUNET_NAT_MiniHandle::unmap_cmd.

Referenced by GNUNET_NAT_mini_map_stop().

633 {
634  struct GNUNET_NAT_MiniHandle *mini = cls;
635 
636  if (NULL == line)
637  {
638  LOG (GNUNET_ERROR_TYPE_DEBUG, "UPnP unmap done\n");
640  mini->unmap_cmd = NULL;
641  GNUNET_free (mini);
642  return;
643  }
644  /* we don't really care about the output... */
645 }
Handle to a mapping created with upnpc.
#define LOG(kind,...)
struct GNUNET_OS_CommandHandle * unmap_cmd
Command used to remove the mapping.
static char * line
Desired phone line (string to be converted to a hash).
void GNUNET_OS_command_stop(struct GNUNET_OS_CommandHandle *cmd)
Stop/kill a command.
Definition: os_priority.c:1076
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_NAT_mini_map_stop()

void GNUNET_NAT_mini_map_stop ( struct GNUNET_NAT_MiniHandle mini)

Remove a mapping created with (mini)upnpc.

Calling this function will give 'upnpc' 1s to remove tha mapping, so while this function is non-blocking, a task will be left with the scheduler for up to 1s past this call.

Parameters
minithe handle

Definition at line 657 of file gnunet-service-nat_mini.c.

References GNUNET_NAT_MiniHandle::ac, GNUNET_NAT_MiniHandle::ac_cls, GNUNET_NAT_MiniHandle::current_addr, GNUNET_NAT_MiniHandle::did_map, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_NAT_ERROR_SUCCESS, GNUNET_NO, GNUNET_OS_command_run(), GNUNET_OS_command_stop(), GNUNET_SCHEDULER_cancel(), GNUNET_snprintf(), GNUNET_NAT_MiniHandle::is_tcp, LOG, GNUNET_NAT_MiniHandle::map_cmd, process_unmap_output(), GNUNET_NAT_MiniHandle::refresh_cmd, GNUNET_NAT_MiniHandle::refresh_task, GNUNET_NAT_MiniHandle::unmap_cmd, and UNMAP_TIMEOUT.

Referenced by client_disconnect_cb().

658 {
659  char pstr[6];
660 
661  if (NULL != mini->refresh_task)
662  {
664  mini->refresh_task = NULL;
665  }
666  if (NULL != mini->refresh_cmd)
667  {
669  mini->refresh_cmd = NULL;
670  }
671  if (NULL != mini->map_cmd)
672  {
674  mini->map_cmd = NULL;
675  }
676  if (GNUNET_NO == mini->did_map)
677  {
678  GNUNET_free (mini);
679  return;
680  }
681  mini->ac (mini->ac_cls,
682  GNUNET_NO,
683  (const struct sockaddr *) &mini->current_addr,
684  sizeof(mini->current_addr),
686  /* Note: oddly enough, deletion uses the external port whereas
687  * addition uses the internal port; this rarely matters since they
688  * often are the same, but it might... */
689  GNUNET_snprintf (pstr,
690  sizeof(pstr),
691  "%u",
692  (unsigned int) ntohs (mini->current_addr.sin_port));
694  "Unmapping port %u with UPnP\n",
695  ntohs (mini->current_addr.sin_port));
697  mini,
699  "upnpc",
700  "upnpc",
701  "-d",
702  pstr,
703  mini->is_tcp ? "tcp" : "udp",
704  NULL);
705 }
static void process_unmap_output(void *cls, const char *line)
Process output from our 'unmap' command.
struct GNUNET_OS_CommandHandle * refresh_cmd
Command used to refresh our map information.
int GNUNET_snprintf(char *buf, size_t size, const char *format,...)
Like snprintf, just aborts if the buffer is of insufficient size.
#define LOG(kind,...)
int is_tcp
Are we mapping TCP or UDP?
#define GNUNET_NO
Definition: gnunet_common.h:78
struct GNUNET_OS_CommandHandle * unmap_cmd
Command used to remove the mapping.
int did_map
Did we succeed with creating a mapping?
struct GNUNET_SCHEDULER_Task * refresh_task
We check the mapping periodically to see if it still works.
void * ac_cls
Closure for ac.
struct GNUNET_OS_CommandHandle * GNUNET_OS_command_run(GNUNET_OS_LineProcessor proc, void *proc_cls, struct GNUNET_TIME_Relative timeout, const char *binary,...)
Run the given command line and call the given function for each line of the output.
Definition: os_priority.c:1161
struct GNUNET_OS_CommandHandle * map_cmd
Command used to install the map.
void GNUNET_OS_command_stop(struct GNUNET_OS_CommandHandle *cmd)
Stop/kill a command.
Definition: os_priority.c:1076
GNUNET_NAT_MiniAddressCallback ac
Function to call on mapping changes.
struct sockaddr_in current_addr
Our current external mapping (if we have one).
#define GNUNET_free(ptr)
Wrapper around free.
#define UNMAP_TIMEOUT
How long do we give upnpc to remove a mapping?
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966
Here is the call graph for this function:
Here is the caller graph for this function: