nat.c | nat.c | |||
---|---|---|---|---|
skipping to change at line 417 | skipping to change at line 417 | |||
enum LocalAddressSource src, | enum LocalAddressSource src, | |||
const struct sockaddr *arg, socklen_t arg_size) | const struct sockaddr *arg, socklen_t arg_size) | |||
{ | { | |||
struct LocalAddressList *lal; | struct LocalAddressList *lal; | |||
lal = GNUNET_malloc (sizeof (struct LocalAddressList) + arg_size); | lal = GNUNET_malloc (sizeof (struct LocalAddressList) + arg_size); | |||
memcpy (&lal[1], arg, arg_size); | memcpy (&lal[1], arg, arg_size); | |||
lal->addrlen = arg_size; | lal->addrlen = arg_size; | |||
lal->source = src; | lal->source = src; | |||
GNUNET_CONTAINER_DLL_insert (h->lal_head, h->lal_tail, lal); | GNUNET_CONTAINER_DLL_insert (h->lal_head, h->lal_tail, lal); | |||
#if DEBUG_NAT | ||||
LOG (GNUNET_ERROR_TYPE_DEBUG, "Adding address `%s' from source %d\n", | LOG (GNUNET_ERROR_TYPE_DEBUG, "Adding address `%s' from source %d\n", | |||
GNUNET_a2s (arg, arg_size), src); | GNUNET_a2s (arg, arg_size), src); | |||
#endif | ||||
if (NULL != h->address_callback) | if (NULL != h->address_callback) | |||
h->address_callback (h->callback_cls, GNUNET_YES, arg, arg_size); | h->address_callback (h->callback_cls, GNUNET_YES, arg, arg_size); | |||
} | } | |||
/** | /** | |||
* Add the given address to the list of 'local' addresses, thereby | * Add the given address to the list of 'local' addresses, thereby | |||
* making it a 'legal' address for this peer to have. Set the | * making it a 'legal' address for this peer to have. Set the | |||
* port number in the process to the advertised port and possibly | * port number in the process to the advertised port and possibly | |||
* also to zero (if we have the gnunet-helper-nat-server). | * also to zero (if we have the gnunet-helper-nat-server). | |||
* | * | |||
skipping to change at line 736 | skipping to change at line 734 | |||
struct sockaddr_in sin_addr; | struct sockaddr_in sin_addr; | |||
h->server_read_task = GNUNET_SCHEDULER_NO_TASK; | h->server_read_task = GNUNET_SCHEDULER_NO_TASK; | |||
if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) | if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) | |||
return; | return; | |||
memset (mybuf, 0, sizeof (mybuf)); | memset (mybuf, 0, sizeof (mybuf)); | |||
bytes = | bytes = | |||
GNUNET_DISK_file_read (h->server_stdout_handle, mybuf, sizeof (mybuf) ); | GNUNET_DISK_file_read (h->server_stdout_handle, mybuf, sizeof (mybuf) ); | |||
if (bytes < 1) | if (bytes < 1) | |||
{ | { | |||
#if DEBUG_NAT | ||||
LOG (GNUNET_ERROR_TYPE_DEBUG, | LOG (GNUNET_ERROR_TYPE_DEBUG, | |||
"Finished reading from server stdout with code: %d\n", bytes); | "Finished reading from server stdout with code: %d\n", bytes); | |||
#endif | ||||
if (0 != GNUNET_OS_process_kill (h->server_proc, SIGTERM)) | if (0 != GNUNET_OS_process_kill (h->server_proc, SIGTERM)) | |||
GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_WARNING, "nat", "kill"); | GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_WARNING, "nat", "kill"); | |||
GNUNET_OS_process_wait (h->server_proc); | GNUNET_OS_process_wait (h->server_proc); | |||
GNUNET_OS_process_close (h->server_proc); | GNUNET_OS_process_destroy (h->server_proc); | |||
h->server_proc = NULL; | h->server_proc = NULL; | |||
GNUNET_DISK_pipe_close (h->server_stdout); | GNUNET_DISK_pipe_close (h->server_stdout); | |||
h->server_stdout = NULL; | h->server_stdout = NULL; | |||
h->server_stdout_handle = NULL; | h->server_stdout_handle = NULL; | |||
/* now try to restart it */ | /* now try to restart it */ | |||
h->server_retry_delay = | h->server_retry_delay = | |||
GNUNET_TIME_relative_multiply (h->server_retry_delay, 2); | GNUNET_TIME_relative_multiply (h->server_retry_delay, 2); | |||
h->server_retry_delay = | h->server_retry_delay = | |||
GNUNET_TIME_relative_max (GNUNET_TIME_UNIT_HOURS, | GNUNET_TIME_relative_max (GNUNET_TIME_UNIT_HOURS, | |||
h->server_retry_delay); | h->server_retry_delay); | |||
skipping to change at line 781 | skipping to change at line 777 | |||
port_start = &mybuf[i + 1]; | port_start = &mybuf[i + 1]; | |||
} | } | |||
} | } | |||
/* construct socket address of sender */ | /* construct socket address of sender */ | |||
memset (&sin_addr, 0, sizeof (sin_addr)); | memset (&sin_addr, 0, sizeof (sin_addr)); | |||
sin_addr.sin_family = AF_INET; | sin_addr.sin_family = AF_INET; | |||
#if HAVE_SOCKADDR_IN_SIN_LEN | #if HAVE_SOCKADDR_IN_SIN_LEN | |||
sin_addr.sin_len = sizeof (sin_addr); | sin_addr.sin_len = sizeof (sin_addr); | |||
#endif | #endif | |||
if ((NULL == port_start) || (1 != sscanf (port_start, "%d", &port)) || | if ((NULL == port_start) || (1 != SSCANF (port_start, "%d", &port)) || | |||
(-1 == inet_pton (AF_INET, mybuf, &sin_addr.sin_addr))) | (-1 == inet_pton (AF_INET, mybuf, &sin_addr.sin_addr))) | |||
{ | { | |||
/* should we restart gnunet-helper-nat-server? */ | /* should we restart gnunet-helper-nat-server? */ | |||
LOG (GNUNET_ERROR_TYPE_WARNING, "nat", | LOG (GNUNET_ERROR_TYPE_WARNING, "nat", | |||
_("gnunet-helper-nat-server generated malformed address `%s'\n"), | _("gnunet-helper-nat-server generated malformed address `%s'\n"), | |||
mybuf); | mybuf); | |||
h->server_read_task = | h->server_read_task = | |||
GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | |||
h->server_stdout_handle, | h->server_stdout_handle, | |||
&nat_server_read, h); | &nat_server_read, h); | |||
return; | return; | |||
} | } | |||
sin_addr.sin_port = htons ((uint16_t) port); | sin_addr.sin_port = htons ((uint16_t) port); | |||
#if DEBUG_NAT | ||||
LOG (GNUNET_ERROR_TYPE_DEBUG, "gnunet-helper-nat-server read: %s:%d\n", m ybuf, | LOG (GNUNET_ERROR_TYPE_DEBUG, "gnunet-helper-nat-server read: %s:%d\n", m ybuf, | |||
port); | port); | |||
#endif | ||||
h->reversal_callback (h->callback_cls, (const struct sockaddr *) &sin_add r, | h->reversal_callback (h->callback_cls, (const struct sockaddr *) &sin_add r, | |||
sizeof (sin_addr)); | sizeof (sin_addr)); | |||
h->server_read_task = | h->server_read_task = | |||
GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | |||
h->server_stdout_handle, &nat_server_ read, | h->server_stdout_handle, &nat_server_ read, | |||
h); | h); | |||
} | } | |||
/** | /** | |||
* Try to start the gnunet-helper-nat-server (if it is not | * Try to start the gnunet-helper-nat-server (if it is not | |||
skipping to change at line 822 | skipping to change at line 816 | |||
*/ | */ | |||
static void | static void | |||
start_gnunet_nat_server (struct GNUNET_NAT_Handle *h) | start_gnunet_nat_server (struct GNUNET_NAT_Handle *h) | |||
{ | { | |||
if ((h->behind_nat == GNUNET_YES) && (h->enable_nat_server == GNUNET_YES) && | if ((h->behind_nat == GNUNET_YES) && (h->enable_nat_server == GNUNET_YES) && | |||
(h->internal_address != NULL) && | (h->internal_address != NULL) && | |||
(NULL != | (NULL != | |||
(h->server_stdout = | (h->server_stdout = | |||
GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES)))) | GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES)))) | |||
{ | { | |||
#if DEBUG_NAT | ||||
LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting `%s' at `%s'\n", | LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting `%s' at `%s'\n", | |||
"gnunet-helper-nat-server", h->internal_address); | "gnunet-helper-nat-server", h->internal_address); | |||
#endif | ||||
/* Start the server process */ | /* Start the server process */ | |||
h->server_proc = | h->server_proc = | |||
GNUNET_OS_start_process (GNUNET_NO, NULL, h->server_stdout, | GNUNET_OS_start_process (GNUNET_NO, NULL, h->server_stdout, | |||
"gnunet-helper-nat-server", | "gnunet-helper-nat-server", | |||
"gnunet-helper-nat-server", | "gnunet-helper-nat-server", | |||
h->internal_address, NULL); | h->internal_address, NULL); | |||
if (h->server_proc == NULL) | if (h->server_proc == NULL) | |||
{ | { | |||
LOG (GNUNET_ERROR_TYPE_WARNING, "nat", _("Failed to start %s\n"), | LOG (GNUNET_ERROR_TYPE_WARNING, "nat", _("Failed to start %s\n"), | |||
"gnunet-helper-nat-server"); | "gnunet-helper-nat-server"); | |||
skipping to change at line 1056 | skipping to change at line 1048 | |||
uint16_t adv_port, unsigned int num_addrs, | uint16_t adv_port, unsigned int num_addrs, | |||
const struct sockaddr **addrs, const socklen_t * addrl ens, | const struct sockaddr **addrs, const socklen_t * addrl ens, | |||
GNUNET_NAT_AddressCallback address_callback, | GNUNET_NAT_AddressCallback address_callback, | |||
GNUNET_NAT_ReversalCallback reversal_callback, | GNUNET_NAT_ReversalCallback reversal_callback, | |||
void *callback_cls) | void *callback_cls) | |||
{ | { | |||
struct GNUNET_NAT_Handle *h; | struct GNUNET_NAT_Handle *h; | |||
struct in_addr in_addr; | struct in_addr in_addr; | |||
unsigned int i; | unsigned int i; | |||
#if DEBUG_NAT | ||||
LOG (GNUNET_ERROR_TYPE_DEBUG, | LOG (GNUNET_ERROR_TYPE_DEBUG, | |||
"Registered with NAT service at port %u with %u IP bound local addre sses\n", | "Registered with NAT service at port %u with %u IP bound local addre sses\n", | |||
(unsigned int) adv_port, num_addrs); | (unsigned int) adv_port, num_addrs); | |||
#endif | ||||
h = GNUNET_malloc (sizeof (struct GNUNET_NAT_Handle)); | h = GNUNET_malloc (sizeof (struct GNUNET_NAT_Handle)); | |||
h->server_retry_delay = GNUNET_TIME_UNIT_SECONDS; | h->server_retry_delay = GNUNET_TIME_UNIT_SECONDS; | |||
h->cfg = cfg; | h->cfg = cfg; | |||
h->is_tcp = is_tcp; | h->is_tcp = is_tcp; | |||
h->address_callback = address_callback; | h->address_callback = address_callback; | |||
h->reversal_callback = reversal_callback; | h->reversal_callback = reversal_callback; | |||
h->callback_cls = callback_cls; | h->callback_cls = callback_cls; | |||
h->num_local_addrs = num_addrs; | h->num_local_addrs = num_addrs; | |||
h->adv_port = adv_port; | h->adv_port = adv_port; | |||
if (num_addrs != 0) | if (num_addrs != 0) | |||
skipping to change at line 1249 | skipping to change at line 1239 | |||
if (GNUNET_SCHEDULER_NO_TASK != h->dns_task) | if (GNUNET_SCHEDULER_NO_TASK != h->dns_task) | |||
{ | { | |||
GNUNET_SCHEDULER_cancel (h->dns_task); | GNUNET_SCHEDULER_cancel (h->dns_task); | |||
h->dns_task = GNUNET_SCHEDULER_NO_TASK; | h->dns_task = GNUNET_SCHEDULER_NO_TASK; | |||
} | } | |||
if (NULL != h->server_proc) | if (NULL != h->server_proc) | |||
{ | { | |||
if (0 != GNUNET_OS_process_kill (h->server_proc, SIGTERM)) | if (0 != GNUNET_OS_process_kill (h->server_proc, SIGTERM)) | |||
GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_WARNING, "nat", "kill"); | GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_WARNING, "nat", "kill"); | |||
GNUNET_OS_process_wait (h->server_proc); | GNUNET_OS_process_wait (h->server_proc); | |||
GNUNET_OS_process_close (h->server_proc); | GNUNET_OS_process_destroy (h->server_proc); | |||
h->server_proc = NULL; | h->server_proc = NULL; | |||
GNUNET_DISK_pipe_close (h->server_stdout); | GNUNET_DISK_pipe_close (h->server_stdout); | |||
h->server_stdout = NULL; | h->server_stdout = NULL; | |||
h->server_stdout_handle = NULL; | h->server_stdout_handle = NULL; | |||
} | } | |||
if (NULL != h->server_stdout) | if (NULL != h->server_stdout) | |||
{ | { | |||
GNUNET_DISK_pipe_close (h->server_stdout); | GNUNET_DISK_pipe_close (h->server_stdout); | |||
h->server_stdout = NULL; | h->server_stdout = NULL; | |||
h->server_stdout_handle = NULL; | h->server_stdout_handle = NULL; | |||
skipping to change at line 1283 | skipping to change at line 1273 | |||
GNUNET_free_non_null (h->external_address); | GNUNET_free_non_null (h->external_address); | |||
GNUNET_free_non_null (h->internal_address); | GNUNET_free_non_null (h->internal_address); | |||
GNUNET_free (h); | GNUNET_free (h); | |||
} | } | |||
/** | /** | |||
* We learned about a peer (possibly behind NAT) so run the | * We learned about a peer (possibly behind NAT) so run the | |||
* gnunet-helper-nat-client to send dummy ICMP responses to cause | * gnunet-helper-nat-client to send dummy ICMP responses to cause | |||
* that peer to connect to us (connection reversal). | * that peer to connect to us (connection reversal). | |||
* | * | |||
* @param h NAT handle for us (largely used for configuration) | * @return GNUNET_SYSERR on error, GNUNET_NO if nat client is disabled, | |||
* @param sa the address of the peer (IPv4-only) | * GNUNET_OK otherwise | |||
*/ | */ | |||
void | int | |||
GNUNET_NAT_run_client (struct GNUNET_NAT_Handle *h, | GNUNET_NAT_run_client (struct GNUNET_NAT_Handle *h, | |||
const struct sockaddr_in *sa) | const struct sockaddr_in *sa) | |||
{ | { | |||
char inet4[INET_ADDRSTRLEN]; | char inet4[INET_ADDRSTRLEN]; | |||
char port_as_string[6]; | char port_as_string[6]; | |||
struct GNUNET_OS_Process *proc; | struct GNUNET_OS_Process *proc; | |||
if (GNUNET_YES != h->enable_nat_client) | if (GNUNET_YES != h->enable_nat_client) | |||
return; /* not permitted / possible */ | return GNUNET_NO; /* not permitted / possible */ | |||
if (h->internal_address == NULL) | if (h->internal_address == NULL) | |||
{ | { | |||
LOG (GNUNET_ERROR_TYPE_WARNING, "nat", | LOG (GNUNET_ERROR_TYPE_WARNING, "nat", | |||
_ | _ | |||
("Internal IP address not known, cannot use ICMP NAT traversal met hod\n")); | ("Internal IP address not known, cannot use ICMP NAT traversal met hod\n")); | |||
return; | return GNUNET_SYSERR; | |||
} | } | |||
GNUNET_assert (sa->sin_family == AF_INET); | GNUNET_assert (sa->sin_family == AF_INET); | |||
if (NULL == inet_ntop (AF_INET, &sa->sin_addr, inet4, INET_ADDRSTRLEN)) | if (NULL == inet_ntop (AF_INET, &sa->sin_addr, inet4, INET_ADDRSTRLEN)) | |||
{ | { | |||
GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_WARNING, "nat", "inet_ntop" ); | GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_WARNING, "nat", "inet_ntop" ); | |||
return; | return GNUNET_SYSERR; | |||
} | } | |||
GNUNET_snprintf (port_as_string, sizeof (port_as_string), "%d", h->adv_po rt); | GNUNET_snprintf (port_as_string, sizeof (port_as_string), "%d", h->adv_po rt); | |||
#if DEBUG_NAT | ||||
LOG (GNUNET_ERROR_TYPE_DEBUG, | LOG (GNUNET_ERROR_TYPE_DEBUG, | |||
_("Running gnunet-helper-nat-client %s %s %u\n"), h->internal_addres s, | _("Running gnunet-helper-nat-client %s %s %u\n"), h->internal_addres s, | |||
inet4, (unsigned int) h->adv_port); | inet4, (unsigned int) h->adv_port); | |||
#endif | ||||
proc = | proc = | |||
GNUNET_OS_start_process (GNUNET_NO, | GNUNET_OS_start_process (GNUNET_NO, | |||
NULL, NULL, "gnunet-helper-nat-client", | NULL, NULL, "gnunet-helper-nat-client", | |||
"gnunet-helper-nat-client", h->internal_addr ess, | "gnunet-helper-nat-client", h->internal_addr ess, | |||
inet4, port_as_string, NULL); | inet4, port_as_string, NULL); | |||
if (NULL == proc) | if (NULL == proc) | |||
return; | return GNUNET_SYSERR; | |||
/* we know that the gnunet-helper-nat-client will terminate virtually | /* we know that the gnunet-helper-nat-client will terminate virtually | |||
* instantly */ | * instantly */ | |||
GNUNET_OS_process_wait (proc); | GNUNET_OS_process_wait (proc); | |||
GNUNET_OS_process_close (proc); | GNUNET_OS_process_destroy (proc); | |||
return GNUNET_OK; | ||||
} | } | |||
/** | /** | |||
* Test if the given address is (currently) a plausible IP address for this peer. | * Test if the given address is (currently) a plausible IP address for this peer. | |||
* | * | |||
* @param h the handle returned by register | * @param h the handle returned by register | |||
* @param addr IP address to test (IPv4 or IPv6) | * @param addr IP address to test (IPv4 or IPv6) | |||
* @param addrlen number of bytes in addr | * @param addrlen number of bytes in addr | |||
* @return GNUNET_YES if the address is plausible, | * @return GNUNET_YES if the address is plausible, | |||
* GNUNET_NO if the address is not plausible, | * GNUNET_NO if the address is not plausible, | |||
End of changes. 23 change blocks. | ||||
23 lines changed or deleted | 13 lines changed or added | |||
This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |