aboutsummaryrefslogtreecommitdiff
path: root/src/nat
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2017-01-07 16:47:07 +0100
committerChristian Grothoff <christian@grothoff.org>2017-01-07 16:47:07 +0100
commitddadc570d8fd3ce7a4f658adf9a2c9b9d9c0dcba (patch)
tree076f4d7b4732099d33662de3bdff51c965cae8df /src/nat
parent659e270f9e023112ca864065a22db5e484ba5ef6 (diff)
remove legacy NAT library logic, or preserve if it might still be useful
Diffstat (limited to 'src/nat')
-rw-r--r--src/nat/Makefile.am70
-rw-r--r--src/nat/gnunet-service-nat.c9
-rw-r--r--src/nat/nat.c2054
-rw-r--r--src/nat/nat_auto.c1081
-rw-r--r--src/nat/nat_mini.c712
-rw-r--r--src/nat/nat_stun.c439
-rw-r--r--src/nat/nat_test.c645
7 files changed, 30 insertions, 4980 deletions
diff --git a/src/nat/Makefile.am b/src/nat/Makefile.am
index 456ddfb62c..3dc001dd79 100644
--- a/src/nat/Makefile.am
+++ b/src/nat/Makefile.am
@@ -60,22 +60,8 @@ if USE_COVERAGE
endif
lib_LTLIBRARIES = \
- libgnunetnat.la \
libgnunetnatnew.la
-libgnunetnat_la_SOURCES = \
- nat.c nat.h \
- nat_auto.c \
- nat_test.c \
- nat_mini.c \
- nat_stun.c
-libgnunetnat_la_LIBADD = \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(GN_LIBINTL) @EXT_LIBS@
-libgnunetnat_la_LDFLAGS = \
- $(GN_LIB_LDFLAGS) $(WINFLAGS) \
- -version-info 1:1:1
-
libgnunetnatnew_la_SOURCES = \
nat_api.c \
nat_api_stun.c nat_stun.h \
@@ -100,40 +86,40 @@ gnunet_service_nat_LDADD = \
-lgcrypt \
$(GN_LIBINTL)
-check_PROGRAMS = \
- test_nat \
- test_nat_mini \
- test_nat_test \
- test_stun
+#check_PROGRAMS = \
+# test_nat \
+# test_nat_mini \
+# test_nat_test \
+# test_stun
if ENABLE_TEST_RUN
AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;
TESTS = $(check_PROGRAMS)
endif
-test_nat_SOURCES = \
- test_nat.c
-test_nat_LDADD = \
- libgnunetnat.la \
- $(top_builddir)/src/util/libgnunetutil.la
-
-test_nat_mini_SOURCES = \
- test_nat_mini.c
-test_nat_mini_LDADD = \
- libgnunetnat.la \
- $(top_builddir)/src/util/libgnunetutil.la
-
-test_nat_test_SOURCES = \
- test_nat_test.c
-test_nat_test_LDADD = \
- libgnunetnat.la \
- $(top_builddir)/src/util/libgnunetutil.la
-
-test_stun_SOURCES = \
- test_stun.c
-test_stun_LDADD = \
- libgnunetnat.la \
- $(top_builddir)/src/util/libgnunetutil.la
+#test_nat_SOURCES = \
+# test_nat.c
+#test_nat_LDADD = \
+# libgnunetnat.la \
+# $(top_builddir)/src/util/libgnunetutil.la
+
+#test_nat_mini_SOURCES = \
+# test_nat_mini.c
+#test_nat_mini_LDADD = \
+# libgnunetnat.la \
+# $(top_builddir)/src/util/libgnunetutil.la
+
+#test_nat_test_SOURCES = \
+# test_nat_test.c
+#test_nat_test_LDADD = \
+# libgnunetnat.la \
+# $(top_builddir)/src/util/libgnunetutil.la
+
+#test_stun_SOURCES = \
+# test_stun.c
+#test_stun_LDADD = \
+# libgnunetnat.la \
+# $(top_builddir)/src/util/libgnunetutil.la
EXTRA_DIST = \
test_nat_data.conf \
diff --git a/src/nat/gnunet-service-nat.c b/src/nat/gnunet-service-nat.c
index b3e81127b8..7fa329b54e 100644
--- a/src/nat/gnunet-service-nat.c
+++ b/src/nat/gnunet-service-nat.c
@@ -28,13 +28,8 @@
* knowledge about the local network topology.
*
* TODO:
- * - adapt existing transports to use new NAT logic
- * - abandon legacy NAT code
- *
- * - implement "more" autoconfig:
- * + consider moving autoconfig-logic into separate service!
- * + re-work gnunet-nat-server & integrate!
- * + test manually punched NAT (how?)
+ * - migrate test cases to new NAT service
+ * - add new traceroute-based logic for external IP detection
*
* - implement & test STUN processing to classify NAT;
* basically, open port & try different methods.
diff --git a/src/nat/nat.c b/src/nat/nat.c
deleted file mode 100644
index 08dd5dd1ec..0000000000
--- a/src/nat/nat.c
+++ /dev/null
@@ -1,2054 +0,0 @@
-/*
- This file is part of GNUnet.
- Copyright (C) 2009, 2010, 2011 GNUnet e.V.
-
- GNUnet is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- 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., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-*/
-
-/**
- * @file nat/nat.c
- * @brief Library handling UPnP and NAT-PMP port forwarding and
- * external IP address retrieval
- * @author Milan Bouchet-Valat
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include "gnunet_util_lib.h"
-#include "gnunet_resolver_service.h"
-#include "gnunet_nat_lib.h"
-#include "nat.h"
-
-#define LOG(kind,...) GNUNET_log_from (kind, "nat", __VA_ARGS__)
-
-/**
- * How often do we scan for changes in our IP address from our local
- * interfaces?
- */
-#define IFC_SCAN_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15)
-
-/**
- * How often do we scan for changes in how our hostname resolves?
- */
-#define HOSTNAME_DNS_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 20)
-
-
-/**
- * How often do we scan for changes in how our external (dyndns) hostname resolves?
- */
-#define DYNDNS_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 7)
-
-/**
- * How long until we give up trying to resolve our own hostname?
- */
-#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
- * to remove all addresses from a certain source when
- * we reevaluate the source.
- */
-enum LocalAddressSource
-{
- /**
- * Address was obtained by DNS resolution of the external hostname
- * given in the configuration (i.e. hole-punched DynDNS setup).
- */
- 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)
- * during the previous iteration (see #3213).
- */
- LAL_EXTERNAL_IP_OLD,
-
- /**
- * Address was obtained by looking up our own hostname in DNS.
- */
- LAL_HOSTNAME_DNS,
-
- /**
- * Address was obtained by scanning our hosts's network interfaces
- * and taking their address (no DNS involved).
- */
- LAL_INTERFACE_ADDRESS,
-
- /**
- * Addresses we were explicitly bound to.
- */
- LAL_BINDTO_ADDRESS,
-
- /**
- * Addresses from UPnP or PMP
- */
- LAL_UPNP,
-
- /**
- * End of the list.
- */
- LAL_END
-};
-
-
-/**
- * List of local addresses that we currently deem valid. Actual
- * struct is followed by the 'struct sockaddr'. Note that the code
- * intentionally makes no attempt to ensure that a particular address
- * is only listed once (especially since it may come from different
- * sources, and the source is an "internal" construct).
- */
-struct LocalAddressList
-{
- /**
- * This is a linked list.
- */
- struct LocalAddressList *next;
-
- /**
- * Previous entry.
- */
- struct LocalAddressList *prev;
-
- /**
- * Number of bytes of address that follow.
- */
- socklen_t addrlen;
-
- /**
- * Origin of the local address.
- */
- enum LocalAddressSource source;
-};
-
-
-/**
- * Handle for miniupnp-based NAT traversal actions.
- */
-struct MiniList
-{
-
- /**
- * Doubly-linked list.
- */
- struct MiniList *next;
-
- /**
- * Doubly-linked list.
- */
- struct MiniList *prev;
-
- /**
- * Handle to mini-action.
- */
- struct GNUNET_NAT_MiniHandle *mini;
-
- /**
- * Local port number that was mapped.
- */
- uint16_t port;
-
-};
-
-
-/**
- * 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.
- */
-struct GNUNET_NAT_Handle
-{
-
- /**
- * Configuration to use.
- */
- const struct GNUNET_CONFIGURATION_Handle *cfg;
-
- /**
- * Function to call when we learn about a new address.
- */
- GNUNET_NAT_AddressCallback address_callback;
-
- /**
- * Function to call when we notice another peer asking for
- * connection reversal.
- */
- GNUNET_NAT_ReversalCallback reversal_callback;
-
- /**
- * Closure for callbacks (@e address_callback and @e reversal_callback)
- */
- void *callback_cls;
-
- /**
- * Handle for (DYN)DNS lookup of our external IP.
- */
- struct GNUNET_RESOLVER_RequestHandle *ext_dns;
-
- /**
- * Handle for request of hostname resolution, non-NULL if pending.
- */
- struct GNUNET_RESOLVER_RequestHandle *hostname_dns;
-
- /**
- * stdout pipe handle for the gnunet-helper-nat-server process
- */
- struct GNUNET_DISK_PipeHandle *server_stdout;
-
- /**
- * stdout file handle (for reading) for the gnunet-helper-nat-server process
- */
- const struct GNUNET_DISK_FileHandle *server_stdout_handle;
-
- /**
- * Linked list of currently valid addresses (head).
- */
- struct LocalAddressList *lal_head;
-
- /**
- * Linked list of currently valid addresses (tail).
- */
- struct LocalAddressList *lal_tail;
-
- /**
- * How long do we wait for restarting a crashed gnunet-helper-nat-server?
- */
- struct GNUNET_TIME_Relative server_retry_delay;
-
- /**
- * ID of select gnunet-helper-nat-server stdout read task
- */
- struct GNUNET_SCHEDULER_Task *server_read_task;
-
- /**
- * ID of interface IP-scan task
- */
- struct GNUNET_SCHEDULER_Task *ifc_task;
-
- /**
- * ID of hostname DNS lookup task
- */
- struct GNUNET_SCHEDULER_Task *hostname_task;
-
- /**
- * ID of DynDNS lookup task
- */
- struct GNUNET_SCHEDULER_Task *dns_task;
-
- /**
- * Active STUN request, if any.
- */
- struct GNUNET_NAT_STUN_Handle *stun_request;
-
- /**
- * How often do we scan for changes in our IP address from our local
- * interfaces?
- */
- struct GNUNET_TIME_Relative ifc_scan_frequency;
-
- /**
- * How often do we scan for changes in how our hostname resolves?
- */
- struct GNUNET_TIME_Relative hostname_dns_frequency;
-
- /**
- * How often do we scan for changes in how our external (dyndns) hostname resolves?
- */
- struct GNUNET_TIME_Relative dyndns_frequency;
-
- /**
- * The process id of the server process (if behind NAT)
- */
- struct GNUNET_OS_Process *server_proc;
-
- /**
- * LAN address as passed by the caller (array).
- */
- struct sockaddr **local_addrs;
-
- /**
- * Length of the @e local_addrs.
- */
- socklen_t *local_addrlens;
-
- /**
- * List of handles for UPnP-traversal, one per local port (if
- * not IPv6-only).
- */
- struct MiniList *mini_head;
-
- /**
- * List of handles for UPnP-traversal, one per local port (if
- * not IPv6-only).
- */
- struct MiniList *mini_tail;
-
- /**
- * Number of entries in 'local_addrs' array.
- */
- unsigned int num_local_addrs;
-
- /**
- * Our external address (according to config, UPnP may disagree...),
- * in dotted decimal notation, IPv4-only. Or NULL if not known.
- */
- char *external_address;
-
- /**
- * Presumably our internal address (according to config)
- */
- char *internal_address;
-
- /**
- * Is this transport configured to be behind a NAT?
- */
- int behind_nat;
-
- /**
- * Has the NAT been punched? (according to config)
- */
- int nat_punched;
-
- /**
- * Is this transport configured to allow connections to NAT'd peers?
- */
- int enable_nat_client;
-
- /**
- * Should we run the gnunet-helper-nat-server?
- */
- int enable_nat_server;
-
- /**
- * Are we allowed to try UPnP/PMP for NAT traversal?
- */
- int enable_upnp;
-
- /**
- * Should we use local addresses (loopback)? (according to config)
- */
- int use_localaddresses;
-
- /**
- * Should we return local addresses to clients
- */
- int return_localaddress;
-
- /**
- * Should we do a DNS lookup of our hostname to find out our own IP?
- */
- int use_hostname;
-
- /**
- * Is using IPv6 disabled?
- */
- int disable_ipv6;
-
- /**
- * Is this TCP or UDP?
- */
- int is_tcp;
-
- /**
- * Port we advertise to the outside.
- */
- 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;
-
-};
-
-
-/**
- * Try to start the gnunet-helper-nat-server (if it is not
- * already running).
- *
- * @param h handle to NAT
- */
-static void
-start_gnunet_nat_server (struct GNUNET_NAT_Handle *h);
-
-
-/**
- * Remove all addresses from the list of 'local' addresses
- * that originated from the given source.
- *
- * @param h handle to NAT
- * @param src source that identifies addresses to remove
- */
-static void
-remove_from_address_list_by_source (struct GNUNET_NAT_Handle *h,
- enum LocalAddressSource src)
-{
- struct LocalAddressList *pos;
- struct LocalAddressList *next;
-
- next = h->lal_head;
- while (NULL != (pos = next))
- {
- next = pos->next;
- if (pos->source != src)
- 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);
- }
-}
-
-
-/**
- * Add the given address to the list of 'local' addresses, thereby
- * making it a 'legal' address for this peer to have.
- *
- * @param h handle to NAT
- * @param src where did the local address originate from?
- * @param arg the address, some `struct sockaddr`
- * @param arg_size number of bytes in @a arg
- */
-static void
-add_to_address_list_as_is (struct GNUNET_NAT_Handle *h,
- enum LocalAddressSource src,
- const struct sockaddr *arg,
- socklen_t arg_size)
-{
- struct LocalAddressList *lal;
-
- lal = GNUNET_malloc (sizeof (struct LocalAddressList) + arg_size);
- GNUNET_memcpy (&lal[1], arg, arg_size);
- lal->addrlen = arg_size;
- lal->source = src;
- GNUNET_CONTAINER_DLL_insert (h->lal_head,
- h->lal_tail,
- lal);
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Adding address `%s' from source %d\n",
- GNUNET_a2s (arg, arg_size),
- src);
- if (NULL != h->address_callback)
- h->address_callback (h->callback_cls,
- GNUNET_YES,
- arg,
- arg_size);
-}
-
-
-/**
- * Add the given address to the list of 'local' addresses, thereby
- * making it a 'legal' address for this peer to have. Set the
- * port number in the process to the advertised port and possibly
- * also to zero (if we have the gnunet-helper-nat-server).
- *
- * @param h handle to NAT
- * @param src where did the local address originate from?
- * @param arg the address, some `struct sockaddr`
- * @param arg_size number of bytes in @a arg
- */
-static void
-add_to_address_list (struct GNUNET_NAT_Handle *h,
- enum LocalAddressSource src,
- const struct sockaddr *arg,
- socklen_t arg_size)
-{
- struct sockaddr_in s4;
- const struct sockaddr_in *in4;
- struct sockaddr_in6 s6;
- const struct sockaddr_in6 *in6;
-
- if (arg_size == sizeof (struct sockaddr_in))
- {
- in4 = (const struct sockaddr_in *) arg;
- s4 = *in4;
- s4.sin_port = htons (h->adv_port);
- add_to_address_list_as_is (h, src, (const struct sockaddr *) &s4,
- sizeof (struct sockaddr_in));
- if (GNUNET_YES == h->enable_nat_server)
- {
- /* also add with PORT = 0 to indicate NAT server is enabled */
- s4.sin_port = htons (0);
- add_to_address_list_as_is (h, src, (const struct sockaddr *) &s4,
- sizeof (struct sockaddr_in));
- }
- }
- else if (arg_size == sizeof (struct sockaddr_in6))
- {
- if (GNUNET_YES != h->disable_ipv6)
- {
- in6 = (const struct sockaddr_in6 *) arg;
- s6 = *in6;
- s6.sin6_port = htons (h->adv_port);
- add_to_address_list_as_is (h, src, (const struct sockaddr *) &s6,
- sizeof (struct sockaddr_in6));
- }
- }
- else
- {
- GNUNET_assert (0);
- }
-}
-
-
-/**
- * Add the given IP address to the list of 'local' addresses, thereby
- * making it a 'legal' address for this peer to have.
- *
- * @param h handle to NAT
- * @param src where did the local address originate from?
- * @param addr the address, some `struct in_addr` or `struct in6_addr`
- * @param addrlen number of bytes in addr
- */
-static void
-add_ip_to_address_list (struct GNUNET_NAT_Handle *h,
- enum LocalAddressSource src,
- const void *addr,
- socklen_t addrlen)
-{
- struct sockaddr_in s4;
- const struct in_addr *in4;
- struct sockaddr_in6 s6;
- const struct in6_addr *in6;
-
- if (addrlen == sizeof (struct in_addr))
- {
- in4 = (const struct in_addr *) addr;
- memset (&s4, 0, sizeof (s4));
- s4.sin_family = AF_INET;
- s4.sin_port = 0;
-#if HAVE_SOCKADDR_IN_SIN_LEN
- s4.sin_len = (u_char) sizeof (struct sockaddr_in);
-#endif
- s4.sin_addr = *in4;
- add_to_address_list (h, src, (const struct sockaddr *) &s4,
- sizeof (struct sockaddr_in));
- if (GNUNET_YES == h->enable_nat_server)
- {
- /* also add with PORT = 0 to indicate NAT server is enabled */
- s4.sin_port = htons (0);
- add_to_address_list (h, src, (const struct sockaddr *) &s4,
- sizeof (struct sockaddr_in));
-
- }
- }
- else if (addrlen == sizeof (struct in6_addr))
- {
- if (GNUNET_YES != h->disable_ipv6)
- {
- in6 = (const struct in6_addr *) addr;
- memset (&s6, 0, sizeof (s6));
- s6.sin6_family = AF_INET6;
- s6.sin6_port = htons (h->adv_port);
-#if HAVE_SOCKADDR_IN_SIN_LEN
- s6.sin6_len = (u_char) sizeof (struct sockaddr_in6);
-#endif
- s6.sin6_addr = *in6;
- add_to_address_list (h, src, (const struct sockaddr *) &s6,
- sizeof (struct sockaddr_in6));
- }
- }
- else
- {
- GNUNET_assert (0);
- }
-}
-
-
-/**
- * Task to do DNS lookup on our external hostname to
- * get DynDNS-IP addresses.
- *
- * @param cls the NAT handle
- */
-static void
-resolve_dns (void *cls);
-
-
-/**
- * Our (external) hostname was resolved and the configuration says that
- * the NAT was hole-punched.
- *
- * @param cls the `struct GNUNET_NAT_Handle`
- * @param addr NULL on error, otherwise result of DNS lookup
- * @param addrlen number of bytes in @a addr
- */
-static void
-process_external_ip (void *cls,
- const struct sockaddr *addr,
- socklen_t addrlen)
-{
- struct GNUNET_NAT_Handle *h = cls;
- struct in_addr dummy;
-
- if (NULL == addr)
- {
- h->ext_dns = NULL;
- /* Current iteration is over, remove 'old' IPs now */
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Purging old IPs for external address\n");
- remove_from_address_list_by_source (h,
- LAL_EXTERNAL_IP_OLD);
- if (1 == inet_pton (AF_INET,
- h->external_address,
- &dummy))
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Got numeric IP for external address, not repeating lookup\n");
- return; /* repated lookup pointless: was numeric! */
- }
- h->dns_task =
- GNUNET_SCHEDULER_add_delayed (h->dyndns_frequency,
- &resolve_dns, h);
- return;
- }
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Got IP `%s' for external address `%s'\n",
- GNUNET_a2s (addr,
- addrlen),
- h->external_address);
- add_to_address_list (h,
- LAL_EXTERNAL_IP,
- addr,
- addrlen);
-}
-
-
-/**
- * Task to do a lookup on our hostname for IP addresses.
- *
- * @param cls the NAT handle
- */
-static void
-resolve_hostname (void *cls);
-
-
-/**
- * Function called by the resolver for each address obtained from DNS
- * for our own hostname. Add the addresses to the list of our IP
- * addresses.
- *
- * @param cls closure
- * @param addr one of the addresses of the host, NULL for the last address
- * @param addrlen length of the @a addr
- */
-static void
-process_hostname_ip (void *cls,
- const struct sockaddr *addr,
- socklen_t addrlen)
-{
- struct GNUNET_NAT_Handle *h = cls;
-
- if (NULL == addr)
- {
- h->hostname_dns = NULL;
- h->hostname_task =
- GNUNET_SCHEDULER_add_delayed (h->hostname_dns_frequency,
- &resolve_hostname,
- h);
- return;
- }
- add_to_address_list (h,
- LAL_HOSTNAME_DNS,
- addr,
- addrlen);
-}
-
-
-/**
- * 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.
- *
- * @param cls the `struct GNUNET_NAT_Handle`
- * @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 @a addr and @a broadcast_addr
- * @return #GNUNET_OK to continue iterating
- */
-static int
-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 static struct in6_addr any6 = IN6ADDR_ANY_INIT;
- struct GNUNET_NAT_Handle *h = cls;
- const struct sockaddr_in *s4;
- const struct sockaddr_in6 *s6;
- const void *ip;
- 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;
- }
- GNUNET_free (tun_if);
- }
- /* 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;
- }
- GNUNET_free (tun_if);
- }
- /* 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;
- }
- GNUNET_free (tun_if);
- }
-
- switch (addr->sa_family)
- {
- case AF_INET:
- /* check if we're bound to the "ANY" IP address */
- have_any = GNUNET_NO;
- for (i=0;i<h->num_local_addrs;i++)
- {
- if (h->local_addrs[i]->sa_family != AF_INET)
- continue;
-#ifndef INADDR_ANY
-#define INADDR_ANY 0
-#endif
- if (INADDR_ANY == ((struct sockaddr_in*) h->local_addrs[i])->sin_addr.s_addr)
- {
- have_any = GNUNET_YES;
- break;
- }
- }
- if (GNUNET_NO == have_any)
- return GNUNET_OK; /* not bound to IP 0.0.0.0 but to specific IP addresses,
- do not use those from interfaces */
- s4 = (struct sockaddr_in *) addr;
- ip = &s4->sin_addr;
-
- /* Check if address is in 127.0.0.0/8 */
- 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;
- }
- if ((GNUNET_YES == h->use_localaddresses) || (value != 0))
- {
- add_ip_to_address_list (h, LAL_INTERFACE_ADDRESS, &s4->sin_addr,
- sizeof (struct in_addr));
- }
- break;
- case AF_INET6:
- /* check if we're bound to the "ANY" IP address */
- have_any = GNUNET_NO;
- for (i=0;i<h->num_local_addrs;i++)
- {
- if (h->local_addrs[i]->sa_family != AF_INET6)
- continue;
- if (0 == memcmp (&any6,
- &((struct sockaddr_in6*) h->local_addrs[i])->sin6_addr,
- sizeof (struct in6_addr)))
- {
- have_any = GNUNET_YES;
- break;
- }
- }
- if (GNUNET_NO == have_any)
- return GNUNET_OK; /* not bound to "ANY" IP (::0) but to specific IP addresses,
- do not use those from interfaces */
-
- s6 = (struct sockaddr_in6 *) addr;
- if (IN6_IS_ADDR_LINKLOCAL (&((struct sockaddr_in6 *) addr)->sin6_addr))
- {
- /* skip link local addresses */
- return GNUNET_OK;
- }
- if ((h->return_localaddress == GNUNET_NO) &&
- (IN6_IS_ADDR_LOOPBACK (&((struct sockaddr_in6 *) addr)->sin6_addr)))
- {
- return GNUNET_OK;
- }
- ip = &s6->sin6_addr;
- if (GNUNET_YES == h->use_localaddresses)
- {
- add_ip_to_address_list (h, LAL_INTERFACE_ADDRESS, &s6->sin6_addr,
- sizeof (struct in6_addr));
- }
- break;
- default:
- GNUNET_break (0);
- return GNUNET_OK;
- }
- if ( (h->internal_address == NULL) &&
- (h->server_proc == NULL) &&
- (h->server_read_task == NULL) &&
- (GNUNET_YES == isDefault) &&
- ( (addr->sa_family == AF_INET) ||
- (addr->sa_family == AF_INET6) ) )
- {
- /* no internal address configured, but we found a "default"
- * interface, try using that as our 'internal' address */
- h->internal_address =
- GNUNET_strdup (inet_ntop (addr->sa_family, ip, buf, sizeof (buf)));
- start_gnunet_nat_server (h);
- }
- return GNUNET_OK;
-}
-
-
-/**
- * Task that restarts the gnunet-helper-nat-server process after a crash
- * after a certain delay.
- *
- * @param cls the `struct GNUNET_NAT_Handle`
- */
-static void
-restart_nat_server (void *cls)
-{
- struct GNUNET_NAT_Handle *h = cls;
-
- h->server_read_task = NULL;
- start_gnunet_nat_server (h);
-}
-
-
-/**
- * We have been notified that gnunet-helper-nat-server has written
- * something to stdout. Handle the output, then reschedule this
- * function to be called again once more is available.
- *
- * @param cls the NAT handle
- */
-static void
-nat_server_read (void *cls)
-{
- struct GNUNET_NAT_Handle *h = cls;
- char mybuf[40];
- ssize_t bytes;
- size_t i;
- int port;
- const char *port_start;
- struct sockaddr_in sin_addr;
-
- h->server_read_task = NULL;
- memset (mybuf, 0, sizeof (mybuf));
- bytes =
- GNUNET_DISK_file_read (h->server_stdout_handle, mybuf, sizeof (mybuf));
- if (bytes < 1)
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Finished reading from server stdout with code: %d\n",
- bytes);
- if (0 != GNUNET_OS_process_kill (h->server_proc, GNUNET_TERM_SIG))
- GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_WARNING, "nat", "kill");
- GNUNET_OS_process_wait (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_STD_BACKOFF (h->server_retry_delay);
- h->server_read_task =
- GNUNET_SCHEDULER_add_delayed (h->server_retry_delay,
- &restart_nat_server, h);
- return;
- }
-
- port_start = NULL;
- for (i = 0; i < sizeof (mybuf); i++)
- {
- if (mybuf[i] == '\n')
- {
- mybuf[i] = '\0';
- break;
- }
- if ((mybuf[i] == ':') && (i + 1 < sizeof (mybuf)))
- {
- mybuf[i] = '\0';
- port_start = &mybuf[i + 1];
- }
- }
-
- /* construct socket address of sender */
- memset (&sin_addr, 0, sizeof (sin_addr));
- sin_addr.sin_family = AF_INET;
-#if HAVE_SOCKADDR_IN_SIN_LEN
- sin_addr.sin_len = sizeof (sin_addr);
-#endif
- 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? */
- LOG (GNUNET_ERROR_TYPE_WARNING, "nat",
- _("gnunet-helper-nat-server generated malformed address `%s'\n"),
- mybuf);
- h->server_read_task =
- GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
- h->server_stdout_handle,
- &nat_server_read, h);
- return;
- }
- sin_addr.sin_port = htons ((uint16_t) port);
- LOG (GNUNET_ERROR_TYPE_DEBUG, "gnunet-helper-nat-server read: %s:%d\n", mybuf,
- port);
- h->reversal_callback (h->callback_cls, (const struct sockaddr *) &sin_addr,
- sizeof (sin_addr));
- h->server_read_task =
- GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
- h->server_stdout_handle,
- &nat_s