X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fnat%2Fnat.c;h=e51c001f2e56a8bcc197227d99851dbb844138cd;hb=e2f70a2f9fa099e3ce0e7451028bea8c373522a6;hp=69c60291c54b01e2c497b1520c1dbf5213cd8d76;hpb=d53ca636148eee4cd5841b7e862935736a107104;p=oweals%2Fgnunet.git diff --git a/src/nat/nat.c b/src/nat/nat.c index 69c60291c..e51c001f2 100644 --- a/src/nat/nat.c +++ b/src/nat/nat.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2009, 2010, 2011 Christian Grothoff (and other contributing authors) + Copyright (C) 2009, 2010, 2011 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -14,8 +14,8 @@ You should have received a copy of the GNU General Public License along with GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ /** @@ -56,6 +56,12 @@ #define HOSTNAME_RESOLVE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1) +/** + * How often do we check a STUN server ? + */ +#define STUN_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 2) + + /** * Where did the given local address originate from? * To be used for debugging as well as in the future @@ -70,6 +76,11 @@ enum LocalAddressSource */ LAL_EXTERNAL_IP, + /** + * Address was obtained by an external STUN server + */ + LAL_EXTERNAL_STUN_IP, + /** * Address was obtained by DNS resolution of the external hostname * given in the configuration (i.e. hole-punched DynDNS setup) @@ -165,6 +176,35 @@ struct MiniList }; +/** + * List of STUN servers + */ +struct StunServerList +{ + + /** + * Doubly-linked list. + */ + struct StunServerList *next; + + /** + * Doubly-linked list. + */ + struct StunServerList *prev; + + /** + * Address + */ + char * address; + + /** + * Server Port + */ + uint16_t port; + +}; + + /** * Handle for active NAT registrations. */ @@ -230,27 +270,22 @@ struct GNUNET_NAT_Handle /** * ID of select gnunet-helper-nat-server stdout read task */ - GNUNET_SCHEDULER_TaskIdentifier server_read_task; + struct GNUNET_SCHEDULER_Task * server_read_task; /** * ID of interface IP-scan task */ - GNUNET_SCHEDULER_TaskIdentifier ifc_task; + struct GNUNET_SCHEDULER_Task * ifc_task; /** * ID of hostname DNS lookup task */ - GNUNET_SCHEDULER_TaskIdentifier hostname_task; + struct GNUNET_SCHEDULER_Task * hostname_task; /** * ID of DynDNS lookup task */ - GNUNET_SCHEDULER_TaskIdentifier dns_task; - - /** - * ID of task to add addresses from bind. - */ - GNUNET_SCHEDULER_TaskIdentifier bind_task; + struct GNUNET_SCHEDULER_Task *dns_task; /** * How often do we scan for changes in our IP address from our local @@ -366,6 +401,46 @@ struct GNUNET_NAT_Handle */ uint16_t adv_port; + /** + * Should we use STUN ? + */ + int use_stun; + + /** + * How often should we check STUN ? + */ + struct GNUNET_TIME_Relative stun_frequency; + + /** + * STUN socket + */ + struct GNUNET_NETWORK_Handle* socket; + + /* + * Am I waiting for a STUN response ? + */ + int waiting_stun; + + /** + * STUN request task + */ + struct GNUNET_SCHEDULER_Task * stun_task; + + /** + * Head of List of STUN servers + */ + struct StunServerList *stun_servers_head; + + /** + * Tail of List of STUN servers + */ + struct StunServerList *stun_servers_tail; + + /** + * Actual STUN Server + */ + struct StunServerList *actual_stun_server; + }; @@ -379,6 +454,20 @@ static void start_gnunet_nat_server (struct GNUNET_NAT_Handle *h); + + +/** + * Call task to process STUN + * + * @param cls handle to NAT + * @param tc TaskContext + */ + +static void +process_stun (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc); + + /** * Remove all addresses from the list of 'local' addresses * that originated from the given source. @@ -650,6 +739,13 @@ process_hostname_ip (void *cls, } +/** + * Length of the interface names returned from os_network.c. + * (in that file, hardcoded at 11). + */ +#define IF_NAME_LEN 11 + + /** * Add the IP of our network interface to the list of * our IP addresses. @@ -664,10 +760,13 @@ process_hostname_ip (void *cls, * @return #GNUNET_OK to continue iterating */ static int -process_interfaces (void *cls, const char *name, int isDefault, +process_interfaces (void *cls, + const char *name, + int isDefault, const struct sockaddr *addr, const struct sockaddr *broadcast_addr, - const struct sockaddr *netmask, socklen_t addrlen) + const struct sockaddr *netmask, + socklen_t addrlen) { const static struct in6_addr any6 = IN6ADDR_ANY_INIT; struct GNUNET_NAT_Handle *h = cls; @@ -677,6 +776,54 @@ process_interfaces (void *cls, const char *name, int isDefault, char buf[INET6_ADDRSTRLEN]; unsigned int i; int have_any; + char *tun_if; + + /* skip virtual interfaces created by GNUnet-vpn */ + if (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_string (h->cfg, + "vpn", + "IFNAME", + &tun_if)) + { + if (0 == strncasecmp (name, + tun_if, + IF_NAME_LEN)) + { + GNUNET_free (tun_if); + return GNUNET_OK; + } + } + /* skip virtual interfaces created by GNUnet-dns */ + if (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_string (h->cfg, + "dns", + "IFNAME", + &tun_if)) + { + if (0 == strncasecmp (name, + tun_if, + IF_NAME_LEN)) + { + GNUNET_free (tun_if); + return GNUNET_OK; + } + } + /* skip virtual interfaces created by GNUnet-exit */ + if (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_string (h->cfg, + "exit", + "TUN_IFNAME", + &tun_if)) + { + if (0 == strncasecmp (name, + tun_if, + IF_NAME_LEN)) + { + GNUNET_free (tun_if); + return GNUNET_OK; + } + } + switch (addr->sa_family) { @@ -710,7 +857,7 @@ process_interfaces (void *cls, const char *name, int isDefault, { return GNUNET_OK; } - if (GNUNET_YES == h->use_localaddresses) + if ((GNUNET_YES == h->use_localaddresses) || (value != 0)) { add_ip_to_address_list (h, LAL_INTERFACE_ADDRESS, &s4->sin_addr, sizeof (struct in_addr)); @@ -758,7 +905,7 @@ process_interfaces (void *cls, const char *name, int isDefault, return GNUNET_OK; } if ((h->internal_address == NULL) && (h->server_proc == NULL) && - (h->server_read_task == GNUNET_SCHEDULER_NO_TASK) && + (h->server_read_task == NULL) && (GNUNET_YES == isDefault) && ((addr->sa_family == AF_INET) || (addr->sa_family == AF_INET6))) { @@ -784,7 +931,7 @@ restart_nat_server (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_NAT_Handle *h = cls; - h->server_read_task = GNUNET_SCHEDULER_NO_TASK; + h->server_read_task = NULL; if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) return; start_gnunet_nat_server (h); @@ -811,7 +958,7 @@ nat_server_read (void *cls, const char *port_start; struct sockaddr_in sin_addr; - h->server_read_task = GNUNET_SCHEDULER_NO_TASK; + h->server_read_task = NULL; if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) return; memset (mybuf, 0, sizeof (mybuf)); @@ -907,7 +1054,7 @@ start_gnunet_nat_server (struct GNUNET_NAT_Handle *h) /* Start the server process */ binary = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-nat-server"); h->server_proc = - GNUNET_OS_start_process (GNUNET_NO, 0, NULL, h->server_stdout, + GNUNET_OS_start_process (GNUNET_NO, 0, NULL, h->server_stdout, NULL, binary, "gnunet-helper-nat-server", h->internal_address, NULL); @@ -946,7 +1093,7 @@ list_interfaces (void *cls, { struct GNUNET_NAT_Handle *h = cls; - h->ifc_task = GNUNET_SCHEDULER_NO_TASK; + h->ifc_task = NULL; remove_from_address_list_by_source (h, LAL_INTERFACE_ADDRESS); GNUNET_OS_network_interfaces_list (&process_interfaces, h); h->ifc_task = @@ -955,6 +1102,132 @@ list_interfaces (void *cls, } + +/** + * Callback if the STun request have a error + * + * @param cls the NAT handle + * @param result , the status + */ +static void +stun_request_callback(void *cls, + enum GNUNET_NAT_StatusCode result) +{ + + struct GNUNET_NAT_Handle *h = cls; + + if(NULL == cls) + return; + + h->waiting_stun = GNUNET_NO; + + if(result != GNUNET_OK) + { + LOG (GNUNET_ERROR_TYPE_WARNING, + "Error processing a STUN request"); + } + +}; + +/** + * CHECK if is a valid STUN packet sending to GNUNET_NAT_stun_handle_packet. + * It also check if it can handle the packet based on the NAT handler. + * You don't need to call anything else to check if the packet is valid, + * + * @param cls the NAT handle + * @param data, packet + * @param len, packet length + * + * @return #GNUNET_NO if it can't decode, #GNUNET_YES if is a packet + */ +int +GNUNET_NAT_is_valid_stun_packet(void *cls, const void *data, size_t len) +{ + struct GNUNET_NAT_Handle *h = cls; + struct sockaddr_in answer; + + /* We are not expecting a STUN message*/ + if(!h->waiting_stun) + return GNUNET_NO; + + /*We dont have STUN installed*/ + if(!h->use_stun) + return GNUNET_NO; + + /* Empty the answer structure */ + memset(&answer, 0, sizeof(struct sockaddr_in)); + + /*Lets handle the packet*/ + int valid = GNUNET_NAT_stun_handle_packet(data,len, &answer); + if(valid) + { + LOG (GNUNET_ERROR_TYPE_INFO, + "Stun server returned IP %s , with port %d \n", inet_ntoa(answer.sin_addr), ntohs(answer.sin_port)); + /* ADD IP AS VALID*/ + add_to_address_list (h, LAL_EXTERNAL_IP, (const struct sockaddr *) &answer, + sizeof (struct sockaddr_in)); + h->waiting_stun = GNUNET_NO; + return GNUNET_YES; + } + else + { + return GNUNET_NO; + } + + + +} + +/** + * Task to do a STUN request + * + * @param cls the NAT handle + * @param tc scheduler context + */ +static void +process_stun (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct GNUNET_NAT_Handle *h = cls; + + h->stun_task = NULL; + + + + struct StunServerList* elem = h->actual_stun_server; + + /* Make the request */ + LOG (GNUNET_ERROR_TYPE_INFO, + "I will request the stun server %s:%i !\n", elem->address, elem->port); + + if(GNUNET_OK == GNUNET_NAT_stun_make_request(elem->address, elem->port, h->socket, &stun_request_callback, NULL)) + { + h->waiting_stun = GNUNET_YES; + } + else + { + LOG (GNUNET_ERROR_TYPE_ERROR, + "STUN request failed %s:%i !\n", elem->address, elem->port); + } + + h->stun_task = + GNUNET_SCHEDULER_add_delayed (h->stun_frequency, + &process_stun, h); + + /* Set actual Server*/ + if(elem->next) + { + h->actual_stun_server = elem->next; + } + else + { + h->actual_stun_server = h->stun_servers_head; + } + +} + + + /** * Task to do a lookup on our hostname for IP addresses. * @@ -967,7 +1240,7 @@ resolve_hostname (void *cls, { struct GNUNET_NAT_Handle *h = cls; - h->hostname_task = GNUNET_SCHEDULER_NO_TASK; + h->hostname_task = NULL; remove_from_address_list_by_source (h, LAL_HOSTNAME_DNS); h->hostname_dns = GNUNET_RESOLVER_hostname_resolve (AF_UNSPEC, HOSTNAME_RESOLVE_TIMEOUT, @@ -989,7 +1262,7 @@ resolve_dns (void *cls, struct GNUNET_NAT_Handle *h = cls; struct LocalAddressList *pos; - h->dns_task = GNUNET_SCHEDULER_NO_TASK; + h->dns_task = NULL; for (pos = h->lal_head; NULL != pos; pos = pos->next) if (pos->source == LAL_EXTERNAL_IP) pos->source = LAL_EXTERNAL_IP_OLD; @@ -1011,39 +1284,64 @@ resolve_dns (void *cls, * the previous (now invalid) one * @param addr either the previous or the new public IP address * @param addrlen actual lenght of @a addr + * @param ret GNUNET_NAT_ERROR_SUCCESS on success, otherwise an error code */ static void upnp_add (void *cls, int add_remove, const struct sockaddr *addr, - socklen_t addrlen) + socklen_t addrlen, + enum GNUNET_NAT_StatusCode ret) { struct GNUNET_NAT_Handle *h = cls; struct LocalAddressList *pos; struct LocalAddressList *next; + + if (GNUNET_NAT_ERROR_SUCCESS != ret) + { + /* Error while running upnp client */ + LOG (GNUNET_ERROR_TYPE_ERROR, + _("Error while running upnp client:\n")); + + //FIXME: convert error code to string + + return; + } + if (GNUNET_YES == add_remove) { add_to_address_list (h, LAL_UPNP, addr, addrlen); return; } - /* remove address */ - next = h->lal_head; - while (NULL != (pos = next)) + else if (GNUNET_NO == add_remove) { - next = pos->next; - if ((pos->source != LAL_UPNP) || (pos->addrlen != addrlen) || - (0 != memcmp (&pos[1], addr, addrlen))) - continue; - GNUNET_CONTAINER_DLL_remove (h->lal_head, h->lal_tail, pos); - if (NULL != h->address_callback) - h->address_callback (h->callback_cls, GNUNET_NO, - (const struct sockaddr *) &pos[1], pos->addrlen); - GNUNET_free (pos); - return; /* only remove once */ + /* remove address */ + next = h->lal_head; + while (NULL != (pos = next)) + { + next = pos->next; + if ((pos->source != LAL_UPNP) || (pos->addrlen != addrlen) || + (0 != memcmp (&pos[1], addr, addrlen))) + continue; + GNUNET_CONTAINER_DLL_remove (h->lal_head, h->lal_tail, pos); + if (NULL != h->address_callback) + h->address_callback (h->callback_cls, GNUNET_NO, + (const struct sockaddr *) &pos[1], pos->addrlen); + GNUNET_free (pos); + return; /* only remove once */ + } + /* asked to remove address that does not exist */ + LOG (GNUNET_ERROR_TYPE_ERROR, + "Asked to remove unkown address `%s'\n", + GNUNET_a2s(addr, addrlen)); + GNUNET_break (0); + } + else + { + + GNUNET_break (0); } - /* asked to remove address that does not exist */ - GNUNET_break (0); } @@ -1066,9 +1364,19 @@ add_minis (struct GNUNET_NAT_Handle *h, return; /* already got this port */ ml = ml->next; } + ml = GNUNET_new (struct MiniList); ml->port = port; ml->mini = GNUNET_NAT_mini_map_start (port, h->is_tcp, &upnp_add, h); + + if (NULL == ml->mini) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Failed to run upnp client for port %u\n"), ml->port); + GNUNET_free (ml); + return; + } + GNUNET_CONTAINER_DLL_insert (h->mini_head, h->mini_tail, ml); } @@ -1076,20 +1384,17 @@ add_minis (struct GNUNET_NAT_Handle *h, /** * Task to add addresses from original bind to set of valid addrs. * - * @param cls the NAT handle - * @param tc scheduler context + * @param h the NAT handle */ static void -add_from_bind (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +add_from_bind (struct GNUNET_NAT_Handle *h) { static struct in6_addr any = IN6ADDR_ANY_INIT; - struct GNUNET_NAT_Handle *h = cls; + unsigned int i; struct sockaddr *sa; const struct sockaddr_in *v4; - h->bind_task = GNUNET_SCHEDULER_NO_TASK; for (i = 0; i < h->num_local_addrs; i++) { sa = h->local_addrs[i]; @@ -1103,10 +1408,16 @@ add_from_bind (void *cls, } v4 = (const struct sockaddr_in *) sa; if (0 != v4->sin_addr.s_addr) - add_to_address_list (h, LAL_BINDTO_ADDRESS, sa, + add_to_address_list (h, + LAL_BINDTO_ADDRESS, sa, sizeof (struct sockaddr_in)); if (h->enable_upnp) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Running upnp client for address `%s'\n", + GNUNET_a2s (sa,sizeof (struct sockaddr_in))); add_minis (h, ntohs (v4->sin_port)); + } break; case AF_INET6: if (sizeof (struct sockaddr_in6) != h->local_addrlens[i]) @@ -1115,9 +1426,12 @@ add_from_bind (void *cls, break; } if (0 != - memcmp (&((const struct sockaddr_in6 *) sa)->sin6_addr, &any, + memcmp (&((const struct sockaddr_in6 *) sa)->sin6_addr, + &any, sizeof (struct in6_addr))) - add_to_address_list (h, LAL_BINDTO_ADDRESS, sa, + add_to_address_list (h, + LAL_BINDTO_ADDRESS, + sa, sizeof (struct sockaddr_in6)); break; default: @@ -1127,7 +1441,6 @@ add_from_bind (void *cls, } - /** * Attempt to enable port redirection and detect public IP address contacting * UPnP or NAT-PMP routers on the local network. Use addr to specify to which @@ -1138,12 +1451,13 @@ add_from_bind (void *cls, * @param is_tcp #GNUNET_YES for TCP, #GNUNET_NO for UDP * @param adv_port advertised port (port we are either bound to or that our OS * locally performs redirection from to our bound port). - * @param num_addrs number of addresses in 'addrs' + * @param num_addrs number of addresses in @a addrs * @param addrs the local addresses packets should be redirected to * @param addrlens actual lengths of the addresses * @param address_callback function to call everytime the public IP address changes * @param reversal_callback function to call if someone wants connection reversal from us * @param callback_cls closure for callbacks + * @param sock used socket * @return NULL on error, otherwise handle that can be used to unregister */ struct GNUNET_NAT_Handle * @@ -1152,10 +1466,11 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, uint16_t adv_port, unsigned int num_addrs, const struct sockaddr **addrs, - const socklen_t * addrlens, + const socklen_t *addrlens, GNUNET_NAT_AddressCallback address_callback, GNUNET_NAT_ReversalCallback reversal_callback, - void *callback_cls) + void *callback_cls, + struct GNUNET_NETWORK_Handle* sock ) { struct GNUNET_NAT_Handle *h; struct in_addr in_addr; @@ -1187,7 +1502,6 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, memcpy (h->local_addrs[i], addrs[i], addrlens[i]); } } - h->bind_task = GNUNET_SCHEDULER_add_now (&add_from_bind, h); if (GNUNET_OK == GNUNET_CONFIGURATION_have_value (cfg, "nat", "INTERNAL_ADDRESS")) { @@ -1248,6 +1562,27 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, if (NULL == reversal_callback) h->enable_nat_server = GNUNET_NO; + /* Check for UPnP client, disable immediately if not available */ + if ( (GNUNET_YES == h->enable_upnp) && + (GNUNET_SYSERR == + GNUNET_OS_check_helper_binary ("upnpc", GNUNET_NO, NULL)) ) + { + LOG (GNUNET_ERROR_TYPE_ERROR, + _("UPnP enabled in configuration, but UPnP client `upnpc` command not found, disabling UPnP \n")); + h->enable_upnp = GNUNET_NO; + } + + /* STUN */ + h->use_stun = + GNUNET_CONFIGURATION_get_value_yesno (cfg, "nat", + "USE_STUN"); + + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_time (cfg, "nat", "STUN_FREQUENCY", + &h->stun_frequency)) + h->stun_frequency = STUN_FREQUENCY; + + /* Check if NAT was hole-punched */ if ((NULL != h->address_callback) && (NULL != h->external_address) && @@ -1256,6 +1591,7 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, h->dns_task = GNUNET_SCHEDULER_add_now (&resolve_dns, h); h->enable_nat_server = GNUNET_NO; h->enable_upnp = GNUNET_NO; + h->use_stun = GNUNET_NO; } else { @@ -1263,6 +1599,96 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, "No external IP address given to add to our list of addresses\n"); } + /* ENABLE STUN ONLY ON UDP*/ + if(!is_tcp && (NULL != sock) && h->use_stun ) + { + h->socket = sock; + h->actual_stun_server = NULL; + + /* Lets process the servers*/ + char *stun_servers; + + size_t urls; + int pos; + size_t pos_port; + + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string (cfg, "nat", "STUN_SERVERS", + &stun_servers)) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING, + "nat", "STUN_SERVERS"); + } + + urls = 0; + h->stun_servers_head = NULL; + h->stun_servers_tail = NULL; + h->actual_stun_server = NULL; + if (strlen (stun_servers) > 0) + { + pos = strlen (stun_servers) - 1; + pos_port = 0; + while (pos >= 0) + { + if (stun_servers[pos] == ':') + { + pos_port = pos + 1; + } + if ((stun_servers[pos] == ' ') || (0 == pos)) + { + + /*Check if we do have a port*/ + if((0 == pos_port) || (pos_port <= pos)) + { + LOG (GNUNET_ERROR_TYPE_WARNING, + "STUN server format mistake\n"); + break; + } + + urls++; + + struct StunServerList* ml = GNUNET_new (struct StunServerList); + + ml->next = NULL; + ml->prev = NULL; + + ml->port = atoi(&stun_servers[pos_port]); + stun_servers[pos_port-1] = '\0'; + + /* Remove trailing space */ + if(stun_servers[pos] == ' ') + ml->address = GNUNET_strdup (&stun_servers[pos + 1]); + else + ml->address = GNUNET_strdup (&stun_servers[pos]); + + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Found STUN server %s port %i !!!\n", ml->address, ml->port); + + GNUNET_CONTAINER_DLL_insert (h->stun_servers_head, h->stun_servers_tail, ml); + /* Make sure that we STOP if is the last one*/ + if(0== pos) + break; + } + + pos--; + } + } + if (urls == 0) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING, + "nat", "STUN_SERVERS"); + } + else + { + /* Set the actual STUN server*/ + h->actual_stun_server = h->stun_servers_head; + } + + h->stun_task = GNUNET_SCHEDULER_add_now(&process_stun, + h); + } + + /* 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) && @@ -1293,10 +1719,13 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, if (NULL != h->address_callback) { - h->ifc_task = GNUNET_SCHEDULER_add_now (&list_interfaces, h); + h->ifc_task = GNUNET_SCHEDULER_add_now (&list_interfaces, + h); if (GNUNET_YES == h->use_hostname) - h->hostname_task = GNUNET_SCHEDULER_add_now (&resolve_hostname, h); + h->hostname_task = GNUNET_SCHEDULER_add_now (&resolve_hostname, + h); } + add_from_bind (h); return h; } @@ -1319,7 +1748,9 @@ GNUNET_NAT_unregister (struct GNUNET_NAT_Handle *h) "NAT unregister called\n"); while (NULL != (ml = h->mini_head)) { - GNUNET_CONTAINER_DLL_remove (h->mini_head, h->mini_tail, ml); + GNUNET_CONTAINER_DLL_remove (h->mini_head, + h->mini_tail, + ml); if (NULL != ml->mini) GNUNET_NAT_mini_map_stop (ml->mini); GNUNET_free (ml); @@ -1334,30 +1765,30 @@ GNUNET_NAT_unregister (struct GNUNET_NAT_Handle *h) GNUNET_RESOLVER_request_cancel (h->hostname_dns); h->hostname_dns = NULL; } - if (GNUNET_SCHEDULER_NO_TASK != h->server_read_task) + if (NULL != h->server_read_task) { GNUNET_SCHEDULER_cancel (h->server_read_task); - h->server_read_task = GNUNET_SCHEDULER_NO_TASK; - } - if (GNUNET_SCHEDULER_NO_TASK != h->bind_task) - { - GNUNET_SCHEDULER_cancel (h->bind_task); - h->bind_task = GNUNET_SCHEDULER_NO_TASK; + h->server_read_task = NULL; } - if (GNUNET_SCHEDULER_NO_TASK != h->ifc_task) + if (NULL != h->ifc_task) { GNUNET_SCHEDULER_cancel (h->ifc_task); - h->ifc_task = GNUNET_SCHEDULER_NO_TASK; + h->ifc_task = NULL; } - if (GNUNET_SCHEDULER_NO_TASK != h->hostname_task) + if (NULL != h->hostname_task) { GNUNET_SCHEDULER_cancel (h->hostname_task); - h->hostname_task = GNUNET_SCHEDULER_NO_TASK; + h->hostname_task = NULL; } - if (GNUNET_SCHEDULER_NO_TASK != h->dns_task) + if (NULL != h->dns_task) { GNUNET_SCHEDULER_cancel (h->dns_task); - h->dns_task = GNUNET_SCHEDULER_NO_TASK; + h->dns_task = NULL; + } + if (NULL != h->stun_task) + { + GNUNET_SCHEDULER_cancel (h->stun_task); + h->stun_task = NULL; } if (NULL != h->server_proc) { @@ -1443,7 +1874,7 @@ GNUNET_NAT_run_client (struct GNUNET_NAT_Handle *h, (unsigned int) h->adv_port); binary = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-nat-client"); proc = - GNUNET_OS_start_process (GNUNET_NO, 0, NULL, NULL, + GNUNET_OS_start_process (GNUNET_NO, 0, NULL, NULL, NULL, binary, "gnunet-helper-nat-client", h->internal_address, @@ -1506,9 +1937,66 @@ GNUNET_NAT_test_address (struct GNUNET_NAT_Handle *h, } } LOG (GNUNET_ERROR_TYPE_WARNING, - "Asked to validate one of my addresses and validation failed!\n"); + "Asked to validate one of my addresses (%s) and validation failed!\n", + GNUNET_a2s (addr, + addrlen)); return GNUNET_NO; } +/** + * Converts enum GNUNET_NAT_StatusCode to a string + * + * @param err error code to resolve to a string + * @return pointer to a static string containing the error code + */ +const char * +GNUNET_NAT_status2string (enum GNUNET_NAT_StatusCode err) +{ + switch (err) + { + case GNUNET_NAT_ERROR_SUCCESS: + return _ ("Operation Successful"); + case GNUNET_NAT_ERROR_IPC_FAILURE: + return _ ("Internal Failure (IPC, ...)"); + case GNUNET_NAT_ERROR_INTERNAL_NETWORK_ERROR: + return _ ("Failure in network subsystem, check permissions."); + case GNUNET_NAT_ERROR_TIMEOUT: + return _ ("Encountered timeout while performing operation"); + case GNUNET_NAT_ERROR_NOT_ONLINE: + return _ ("detected that we are offline"); + case GNUNET_NAT_ERROR_UPNPC_NOT_FOUND: + return _ ("`upnpc` command not found"); + case GNUNET_NAT_ERROR_UPNPC_FAILED: + return _ ("Failed to run `upnpc` command"); + case GNUNET_NAT_ERROR_UPNPC_TIMEOUT: + return _ ("`upnpc' command took too long, process killed"); + case GNUNET_NAT_ERROR_UPNPC_PORTMAP_FAILED: + return _ ("`upnpc' command failed to establish port mapping"); + case GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_NOT_FOUND: + return _ ("`external-ip' command not found"); + case GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_FAILED: + return _ ("Failed to run `external-ip` command"); + case GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_OUTPUT_INVALID: + return _ ("`external-ip' command output invalid"); + case GNUNET_NAT_ERROR_EXTERNAL_IP_ADDRESS_INVALID: + return _ ("no valid address was returned by `external-ip'"); + case GNUNET_NAT_ERROR_NO_VALID_IF_IP_COMBO: + return _ ("Could not determine interface with internal/local network address"); + case GNUNET_NAT_ERROR_HELPER_NAT_SERVER_NOT_FOUND: + return _ ("No functioning gnunet-helper-nat-server installation found"); + case GNUNET_NAT_ERROR_NAT_TEST_START_FAILED: + return _ ("NAT test could not be initialized"); + case GNUNET_NAT_ERROR_NAT_TEST_TIMEOUT: + return _ ("NAT test timeout reached"); + case GNUNET_NAT_ERROR_NAT_REGISTER_FAILED: + return _ ("could not register NAT"); + case GNUNET_NAT_ERROR_HELPER_NAT_CLIENT_NOT_FOUND: + return _ ("No working gnunet-helper-nat-client installation found"); +/* case: + return _ ("");*/ + default: + return "unknown status code"; + } +} /* end of nat.c */