X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fnat%2Fnat.c;h=dd63224c0a425890bc9904a7a3d4e2c91f175af3;hb=70466ec3c34f9a920e9e798e3169f886e9486a59;hp=2040451d5c0306c0cd8dd67e43d892df95b85586;hpb=0a82c8fd7bb83ab64797838aaeddce34b8d67fcf;p=oweals%2Fgnunet.git diff --git a/src/nat/nat.c b/src/nat/nat.c index 2040451d5..dd63224c0 100644 --- a/src/nat/nat.c +++ b/src/nat/nat.c @@ -422,10 +422,8 @@ add_to_address_list_as_is (struct GNUNET_NAT_Handle *h, lal->addrlen = arg_size; lal->source = src; 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", GNUNET_a2s (arg, arg_size), src); -#endif if (NULL != h->address_callback) h->address_callback (h->callback_cls, GNUNET_YES, arg, arg_size); } @@ -629,12 +627,16 @@ process_hostname_ip (void *cls, const struct sockaddr *addr, socklen_t addrlen) * @param name name of the interface * @param isDefault do we think this may be our default interface * @param addr address of the interface + * @param broadcast_addr the broadcast address (can be NULL for unknown or unassigned) + * @param netmask the network mask (can be NULL for unknown or unassigned)) * @param addrlen number of bytes in addr * @return GNUNET_OK to continue iterating */ static int process_interfaces (void *cls, const char *name, int isDefault, - const struct sockaddr *addr, socklen_t addrlen) + const struct sockaddr *addr, + const struct sockaddr *broadcast_addr, + const struct sockaddr *netmask, socklen_t addrlen) { struct GNUNET_NAT_Handle *h = cls; const struct sockaddr_in *s4; @@ -649,8 +651,9 @@ process_interfaces (void *cls, const char *name, int isDefault, ip = &s4->sin_addr; /* Check if address is in 127.0.0.0/8 */ - uint32_t address = ntohl((in_addr_t)(s4->sin_addr.s_addr)); + uint32_t address = ntohl ((uint32_t) (s4->sin_addr.s_addr)); uint32_t value = (address & 0xFF000000) ^ 0x7F000000; + if ((h->return_localaddress == GNUNET_NO) && (value == 0)) { return GNUNET_OK; @@ -745,24 +748,18 @@ nat_server_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_DISK_file_read (h->server_stdout_handle, mybuf, sizeof (mybuf)); if (bytes < 1) { -#if DEBUG_NAT LOG (GNUNET_ERROR_TYPE_DEBUG, "Finished reading from server stdout with code: %d\n", bytes); -#endif if (0 != GNUNET_OS_process_kill (h->server_proc, SIGTERM)) GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_WARNING, "nat", "kill"); 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; GNUNET_DISK_pipe_close (h->server_stdout); h->server_stdout = NULL; h->server_stdout_handle = NULL; /* now try to restart it */ - h->server_retry_delay = - GNUNET_TIME_relative_multiply (h->server_retry_delay, 2); - h->server_retry_delay = - GNUNET_TIME_relative_max (GNUNET_TIME_UNIT_HOURS, - h->server_retry_delay); + h->server_retry_delay = GNUNET_TIME_STD_BACKOFF (h->server_retry_delay); h->server_read_task = GNUNET_SCHEDULER_add_delayed (h->server_retry_delay, &restart_nat_server, h); @@ -790,7 +787,7 @@ nat_server_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) #if HAVE_SOCKADDR_IN_SIN_LEN sin_addr.sin_len = sizeof (sin_addr); #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))) { /* should we restart gnunet-helper-nat-server? */ @@ -804,10 +801,8 @@ nat_server_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) return; } sin_addr.sin_port = htons ((uint16_t) port); -#if DEBUG_NAT LOG (GNUNET_ERROR_TYPE_DEBUG, "gnunet-helper-nat-server read: %s:%d\n", mybuf, port); -#endif h->reversal_callback (h->callback_cls, (const struct sockaddr *) &sin_addr, sizeof (sin_addr)); h->server_read_task = @@ -826,22 +821,24 @@ nat_server_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) static void start_gnunet_nat_server (struct GNUNET_NAT_Handle *h) { + char *binary; + if ((h->behind_nat == GNUNET_YES) && (h->enable_nat_server == GNUNET_YES) && (h->internal_address != NULL) && (NULL != (h->server_stdout = - GNUNET_DISK_pipe (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", "gnunet-helper-nat-server", h->internal_address); -#endif /* Start the server process */ + binary = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-nat-server"); h->server_proc = - GNUNET_OS_start_process (NULL, h->server_stdout, - "gnunet-helper-nat-server", + GNUNET_OS_start_process (GNUNET_NO, 0, NULL, h->server_stdout, + binary, "gnunet-helper-nat-server", h->internal_address, NULL); + GNUNET_free (binary); if (h->server_proc == NULL) { LOG (GNUNET_ERROR_TYPE_WARNING, "nat", _("Failed to start %s\n"), @@ -1073,12 +1070,11 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, int is_tcp, struct GNUNET_NAT_Handle *h; struct in_addr in_addr; unsigned int i; + char *binary; -#if DEBUG_NAT LOG (GNUNET_ERROR_TYPE_DEBUG, "Registered with NAT service at port %u with %u IP bound local addresses\n", (unsigned int) adv_port, num_addrs); -#endif h = GNUNET_malloc (sizeof (struct GNUNET_NAT_Handle)); h->server_retry_delay = GNUNET_TIME_UNIT_SECONDS; h->cfg = cfg; @@ -1112,9 +1108,9 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, int is_tcp, if ((h->internal_address != NULL) && (inet_pton (AF_INET, h->internal_address, &in_addr) != 1)) { - LOG (GNUNET_ERROR_TYPE_WARNING, "nat", - _("Malformed %s `%s' given in configuration!\n"), "INTERNAL_ADDRESS", - h->internal_address); + GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING, + "nat", "INTERNAL_ADDRESS", + _("malformed")); GNUNET_free (h->internal_address); h->internal_address = NULL; } @@ -1131,15 +1127,16 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, int is_tcp, h->nat_punched = GNUNET_CONFIGURATION_get_value_yesno (cfg, "nat", "PUNCHED_NAT"); h->enable_nat_client = - GNUNET_CONFIGURATION_get_value_yesno (cfg, "nat", "ENABLE_NAT_CLIENT"); + GNUNET_CONFIGURATION_get_value_yesno (cfg, "nat", "ENABLE_ICMP_CLIENT"); h->enable_nat_server = - GNUNET_CONFIGURATION_get_value_yesno (cfg, "nat", "ENABLE_NAT_SERVER"); + GNUNET_CONFIGURATION_get_value_yesno (cfg, "nat", "ENABLE_ICMP_SERVER"); h->enable_upnp = GNUNET_CONFIGURATION_get_value_yesno (cfg, "nat", "ENABLE_UPNP"); h->use_localaddresses = GNUNET_CONFIGURATION_get_value_yesno (cfg, "nat", "USE_LOCALADDR"); h->return_localaddress = - GNUNET_CONFIGURATION_get_value_yesno (cfg, "nat", "RETURN_LOCAL_ADDRESSES"); + GNUNET_CONFIGURATION_get_value_yesno (cfg, "nat", + "RETURN_LOCAL_ADDRESSES"); h->use_hostname = GNUNET_CONFIGURATION_get_value_yesno (cfg, "nat", "USE_HOSTNAME"); @@ -1171,9 +1168,10 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, int is_tcp, } /* Test for SUID binaries */ + binary = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-nat-server"); if ((h->behind_nat == GNUNET_YES) && (GNUNET_YES == h->enable_nat_server) && (GNUNET_YES != - GNUNET_OS_check_helper_binary ("gnunet-helper-nat-server"))) + GNUNET_OS_check_helper_binary (binary))) { h->enable_nat_server = GNUNET_NO; LOG (GNUNET_ERROR_TYPE_WARNING, @@ -1181,9 +1179,11 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, int is_tcp, ("Configuration requires `%s', but binary is not installed properly (SUID bit not set). Option disabled.\n"), "gnunet-helper-nat-server"); } + GNUNET_free (binary); + binary = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-nat-client"); if ((GNUNET_YES == h->enable_nat_client) && (GNUNET_YES != - GNUNET_OS_check_helper_binary ("gnunet-helper-nat-client"))) + GNUNET_OS_check_helper_binary (binary))) { h->enable_nat_client = GNUNET_NO; LOG (GNUNET_ERROR_TYPE_WARNING, @@ -1191,7 +1191,7 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, int is_tcp, ("Configuration requires `%s', but binary is not installed properly (SUID bit not set). Option disabled.\n"), "gnunet-helper-nat-client"); } - + GNUNET_free (binary); start_gnunet_nat_server (h); /* FIXME: add support for UPnP, etc */ @@ -1267,7 +1267,7 @@ GNUNET_NAT_unregister (struct GNUNET_NAT_Handle *h) if (0 != GNUNET_OS_process_kill (h->server_proc, SIGTERM)) GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_WARNING, "nat", "kill"); 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; GNUNET_DISK_pipe_close (h->server_stdout); h->server_stdout = NULL; @@ -1302,49 +1302,54 @@ GNUNET_NAT_unregister (struct GNUNET_NAT_Handle *h) * gnunet-helper-nat-client to send dummy ICMP responses to cause * that peer to connect to us (connection reversal). * - * @param h NAT handle for us (largely used for configuration) - * @param sa the address of the peer (IPv4-only) + * @return GNUNET_SYSERR on error, GNUNET_NO if nat client is disabled, + * GNUNET_OK otherwise */ -void +int GNUNET_NAT_run_client (struct GNUNET_NAT_Handle *h, const struct sockaddr_in *sa) + + { char inet4[INET_ADDRSTRLEN]; char port_as_string[6]; struct GNUNET_OS_Process *proc; + char *binary; if (GNUNET_YES != h->enable_nat_client) - return; /* not permitted / possible */ + return GNUNET_NO; /* not permitted / possible */ if (h->internal_address == NULL) { LOG (GNUNET_ERROR_TYPE_WARNING, "nat", _ ("Internal IP address not known, cannot use ICMP NAT traversal method\n")); - return; + return GNUNET_SYSERR; } GNUNET_assert (sa->sin_family == AF_INET); if (NULL == inet_ntop (AF_INET, &sa->sin_addr, inet4, INET_ADDRSTRLEN)) { 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_port); -#if DEBUG_NAT LOG (GNUNET_ERROR_TYPE_DEBUG, _("Running gnunet-helper-nat-client %s %s %u\n"), h->internal_address, inet4, (unsigned int) h->adv_port); -#endif + binary = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-nat-client"); proc = - GNUNET_OS_start_process (NULL, NULL, "gnunet-helper-nat-client", + GNUNET_OS_start_process (GNUNET_NO, 0, NULL, NULL, + binary, "gnunet-helper-nat-client", h->internal_address, inet4, port_as_string, NULL); + GNUNET_free (binary); if (NULL == proc) - return; + return GNUNET_SYSERR; /* we know that the gnunet-helper-nat-client will terminate virtually * instantly */ GNUNET_OS_process_wait (proc); - GNUNET_OS_process_close (proc); + GNUNET_OS_process_destroy (proc); + return GNUNET_OK; }