32 #define LOG(kind, ...) GNUNET_log_from (kind, "nat", __VA_ARGS__) 37 #define MAP_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15) 42 #define UNMAP_TIMEOUT \ 43 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1) 48 #define MAP_REFRESH_FREQ \ 49 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5) 122 sizeof(eh->
buf) - eh->
off);
134 if ((eh->
off > 7) && (eh->
buf[eh->
off - 1] ==
'\n'))
136 eh->
buf[eh->
off - 1] =
'\0';
137 if (1 == inet_pton (AF_INET, eh->
buf, &addr))
139 if (0 == addr.s_addr)
194 "Running `external-ip' to determine our external IP\n");
196 if (NULL == eh->
opipe)
240 if (NULL != eh->
opipe)
245 if (NULL != eh->
task)
290 struct sockaddr_in current_addr;
357 mini->
is_tcp ?
"tcp" :
"udp",
413 s = strstr (line,
"ExternalIPAddress = ");
416 s += strlen (
"ExternalIPAddress = ");
417 if (1 != inet_pton (AF_INET, s, &exip))
446 if (NULL == (s = strstr (line,
"->")))
448 if (NULL == strstr (s, pstr))
450 if (1 != sscanf (line,
451 (mini->
is_tcp) ?
"%*u TCP %u->%*s:%*u %*s" 452 :
"%*u UDP %u->%*s:%*u %*s",
488 "Running `upnpc' to check if our mapping still exists\n");
555 if ((NULL == (ipaddr = strstr (line,
" "))) ||
556 (NULL == (pstr = strstr (ipaddr,
":"))) ||
557 (1 != sscanf (pstr + 1,
"%u", &port)))
562 strstr (ipa,
":")[0] =
'\0';
563 if (1 != inet_pton (AF_INET, ipa, &mini->
current_addr.sin_addr))
572 #if HAVE_SOCKADDR_IN_SIN_LEN 573 mini->
current_addr.sin_len =
sizeof(
struct sockaddr_in);
693 "Unmapping port %u with UPnP\n",
702 mini->
is_tcp ?
"tcp" :
"udp",
static void process_unmap_output(void *cls, const char *line)
Process output from our 'unmap' command.
struct GNUNET_OS_Process * GNUNET_OS_start_process(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.
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.
Opaque handle to cancel "GNUNET_NAT_mini_get_external_ipv4" operation.
#define MAP_REFRESH_FREQ
How often do we check for changes in the mapping?
void GNUNET_OS_process_destroy(struct GNUNET_OS_Process *proc)
Cleans up process structure contents (OS-dependent) and deallocates it.
struct GNUNET_OS_CommandHandle * refresh_cmd
Command used to refresh our map information.
Handle to a mapping created with upnpc.
`upnpc' command failed to establish port mapping
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.
static void do_refresh(void *cls)
Run "upnpc -l" to find out if our mapping changed.
enum GNUNET_NAT_StatusCode ret
Error code for better debugging and user feedback.
`upnpc' command took too long, process killed
int is_tcp
Are we mapping TCP or UDP?
struct GNUNET_OS_Process * eip
Handle to external-ip process.
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...
static void process_map_output(void *cls, const char *line)
Process the output from the "upnpc -r" command.
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.
struct GNUNET_OS_CommandHandle * unmap_cmd
Command used to remove the mapping.
#define MAP_TIMEOUT
How long do we give upnpc to create a mapping?
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
GNUNET_NAT_IPCallback cb
Function to call with the result.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
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.
`external-ip' command output invalid
int GNUNET_snprintf(char *buf, size_t size, const char *format,...) __attribute__((format(printf
Like snprintf, just aborts if the buffer is of insufficient size.
void GNUNET_NAT_mini_map_stop(struct GNUNET_NAT_MiniHandle *mini)
Remove a mapping created with (mini)upnpc.
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.
static char * line
Desired phone line (string to be converted to a hash).
No standard streams should be inherited.
enum GNUNET_GenericReturnValue GNUNET_DISK_pipe_close(struct GNUNET_DISK_PipeHandle *p)
Closes an interprocess channel.
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.
static void signal_external_ip_error(void *cls)
(Asynchronously) signal error invoking external-ip to client.
GNUNET_NAT_StatusCode
Error Types for the NAT subsystem (which can then later be converted/resolved to a string) ...
enum GNUNET_GenericReturnValue GNUNET_DISK_pipe_close_end(struct GNUNET_DISK_PipeHandle *p, enum GNUNET_DISK_PipeEnd end)
Closes one half of an interprocess channel.
#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_SCHEDULER_Task * refresh_task
We check the mapping periodically to see if it still works.
void * ac_cls
Closure for ac.
struct GNUNET_DISK_PipeHandle * GNUNET_DISK_pipe(enum GNUNET_DISK_PipeFlags pf)
Creates an interprocess channel.
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.
uint16_t port
Which port are we mapping?
void(* GNUNET_NAT_MiniAddressCallback)(void *cls, int add_remove, const struct sockaddr *addr, socklen_t addrlen, enum GNUNET_NAT_StatusCode result)
Signature of the callback passed to GNUNET_NAT_register() for a function to call whenever our set of ...
size_t off
Number of bytes in buf that are valid.
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.
`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.
void(* GNUNET_NAT_IPCallback)(void *cls, const struct in_addr *addr, enum GNUNET_NAT_StatusCode result)
Signature of a callback that is given an IP address.
Messages for interaction with gnunet-nat-server and gnunet-nat-service.
int GNUNET_OS_process_wait(struct GNUNET_OS_Process *proc)
Wait for a process to terminate.
static uint16_t port
Port number.
struct GNUNET_DISK_PipeHandle * opipe
Handle to stdout pipe of external-ip.
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.
Failed to run upnpc command.
int found
Did we find our mapping during refresh scan?
Configure both pipe ends for blocking operations if set.
Entry in list of pending tasks.
"no valid address was returned by `external-ip'"
void GNUNET_OS_command_stop(struct GNUNET_OS_CommandHandle *cmd)
Stop/kill a command.
GNUNET_NAT_MiniAddressCallback ac
Function to call on mapping changes.
char buf[17]
Destination of our read operation (output of 'external-ip').
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.
Handle used to access files (and pipes).
Handle used to manage a pipe.
Failed to run external-ip command.
void GNUNET_NAT_mini_get_external_ipv4_cancel_(struct GNUNET_NAT_ExternalHandle *eh)
Cancel operation.
void * cb_cls
Closure for cb.
#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.
#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.