summaryrefslogtreecommitdiff
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
parent659e270f9e023112ca864065a22db5e484ba5ef6 (diff)
remove legacy NAT library logic, or preserve if it might still be useful
-rw-r--r--ChangeLog3
-rw-r--r--src/nat-auto/gnunet-nat-auto_legacy.c (renamed from src/nat/nat_test.c)0
-rw-r--r--src/nat-auto/gnunet-service-nat-auto.c3
-rw-r--r--src/nat-auto/gnunet-service-nat-auto_legacy.c (renamed from src/nat/nat_auto.c)0
-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_mini.c712
-rw-r--r--src/nat/nat_stun.c439
-rw-r--r--src/peerinfo-tool/Makefile.am1
-rw-r--r--src/transport/Makefile.am7
11 files changed, 36 insertions, 3262 deletions
diff --git a/ChangeLog b/ChangeLog
index e69de29bb..a44065ec2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -0,0 +1,3 @@
+Sat Jan 7 16:41:34 CET 2017
+ Converting NAT library to new NAT service (and
+ splitting of nat-auto service for auto-configuration). -CG
diff --git a/src/nat/nat_test.c b/src/nat-auto/gnunet-nat-auto_legacy.c
index 803ff23e3..803ff23e3 100644
--- a/src/nat/nat_test.c
+++ b/src/nat-auto/gnunet-nat-auto_legacy.c
diff --git a/src/nat-auto/gnunet-service-nat-auto.c b/src/nat-auto/gnunet-service-nat-auto.c
index f4e1b09e4..fafc4d382 100644
--- a/src/nat-auto/gnunet-service-nat-auto.c
+++ b/src/nat-auto/gnunet-service-nat-auto.c
@@ -27,6 +27,7 @@
* - merge client handle and autoconfig context
* - implement "more" autoconfig:
* + re-work gnunet-nat-server & integrate!
+ * + integrate "legacy" code
* + test manually punched NAT (how?)
*/
#include "platform.h"
@@ -450,7 +451,7 @@ client_disconnect_cb (void *cls,
* Define "main" method using service macro.
*/
GNUNET_SERVICE_MAIN
-("nat",
+("nat-auto",
GNUNET_SERVICE_OPTION_NONE,
&run,
&client_connect_cb,
diff --git a/src/nat/nat_auto.c b/src/nat-auto/gnunet-service-nat-auto_legacy.c
index 061d0cbe6..061d0cbe6 100644
--- a/src/nat/nat_auto.c
+++ b/src/nat-auto/gnunet-service-nat-auto_legacy.c
diff --git a/src/nat/Makefile.am b/src/nat/Makefile.am
index 456ddfb62..3dc001dd7 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 b3e81127b..7fa329b54 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 08dd5dd1e..000000000
--- 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_server_read,
- h);
-}
-
-
-/**
- * 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)
-{
- 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_YES, GNUNET_NO, GNUNET_YES))))
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Starting `%s' at `%s'\n",
- "gnunet-helper-nat-server", h->internal_address);
- /* 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, NULL,
- 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"),
- "gnunet-helper-nat-server");
- GNUNET_DISK_pipe_close (h->server_stdout);
- h->server_stdout = NULL;
- }
- else
- {
- /* Close the write end of the read pipe */
- GNUNET_DISK_pipe_close_end (h->server_stdout, GNUNET_DISK_PIPE_END_WRITE);
- h->server_stdout_handle =
- GNUNET_DISK_pipe_handle (h->server_stdout, GNUNET_DISK_PIPE_END_READ);
- h->server_read_task =
- GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
- h->server_stdout_handle,
- &nat_server_read, h);
- }
- }
-}
-
-
-/**
- * Task to scan the local network interfaces for IP addresses.
- *
- * @param cls the NAT handle
- */
-static void
-list_interfaces (void *cls)
-{
- struct GNUNET_NAT_Handle *h = cls;
-
- 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 =
- GNUNET_SCHEDULER_add_delayed (h->ifc_scan_frequency,
- &list_interfaces, h);
-}
-
-
-/**
- * Callback with the result from the STUN request.
- *
- * @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;
-
- h->stun_request = NULL;
- switch (result)
- {
- case GNUNET_NAT_ERROR_INTERNAL_NETWORK_ERROR:
- LOG (GNUNET_ERROR_TYPE_WARNING,
- "Failed to transmit STUN request\n");
- break;
- case GNUNET_NAT_ERROR_NOT_ONLINE:
- LOG (GNUNET_ERROR_TYPE_WARNING,
- "Failed to resolve STUN server (are we online?)\n");
- break;
- case GNUNET_NAT_ERROR_SUCCESS:
- /* all good, STUN request active */
- h->waiting_stun = GNUNET_YES;
- break;
- default:
- /* unexpected error code for STUN */
- GNUNET_break (0);
- }
-}
-
-
-/**
- * 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 (GNUNET_YES != 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*/
- if (GNUNET_NO ==
- GNUNET_NAT_stun_handle_packet (data,
- len,
- &answer))
- return GNUNET_NO;
-
- LOG (GNUNET_ERROR_TYPE_INFO,
- "STUN server returned %s:%d\n",
- inet_ntoa (answer.sin_addr),
- ntohs (answer.sin_port));
- /* Remove old IPs from previous STUN calls */
- remove_from_address_list_by_source (h,
- LAL_EXTERNAL_STUN_IP);
- /* Add new IP from STUN packet */
- add_to_address_list (h,
- LAL_EXTERNAL_STUN_IP,
- (const struct sockaddr *) &answer,
- sizeof (struct sockaddr_in));
- h->waiting_stun = GNUNET_NO;
- return GNUNET_YES;
-}
-
-
-/**
- * Task to do a STUN request
- *
- * @param cls the NAT handle
- */
-static void
-process_stun (void *cls)
-{
- struct GNUNET_NAT_Handle *h = cls;
- struct StunServerList *elem = h->actual_stun_server;
-
- h->stun_task = NULL;
- /* Make the request */
- LOG (GNUNET_ERROR_TYPE_INFO,
- "I will request the stun server %s:%i\n",
- elem->address,
- elem->port);
- if (NULL != h->stun_request)
- {
- GNUNET_NAT_stun_make_request_cancel (h->stun_request);
- h->stun_request = NULL;
- }
- h->waiting_stun = GNUNET_NO;
- h->stun_request
- = GNUNET_NAT_stun_make_request (elem->address,
- elem->port,
- h->socket,
- &stun_request_callback,
- h);
- if (NULL == h->stun_request)
- {
- LOG (GNUNET_ERROR_TYPE_ERROR,
- "STUN request to %s:%i failed\n",
- elem->address,
- elem->port);
- }
- h->stun_task =
- GNUNET_SCHEDULER_add_delayed (h->stun_frequency,
- &process_stun,
- h);
-
- /* Set actual Server*/
- if (NULL != 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.
- *
- * @param cls the NAT handle
- */
-static void
-resolve_hostname (void *cls)
-{
- struct GNUNET_NAT_Handle *h = cls;
-
- h->hostname_task = NULL;
- remove_from_address_list_by_source (h, LAL_HOSTNAME_DNS);
- GNUNET_assert (NULL == h->hostname_dns);
- h->hostname_dns =
- GNUNET_RESOLVER_hostname_resolve (AF_UNSPEC,
- HOSTNAME_RESOLVE_TIMEOUT,
- &process_hostname_ip,
- h);
-}
-
-
-/**
- * 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)
-{
- struct GNUNET_NAT_Handle *h = cls;
- struct LocalAddressList *pos;
-
- 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;
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Resolving external address `%s'\n",
- h->external_address);
- GNUNET_assert (NULL == h->ext_dns);
- h->ext_dns =
- GNUNET_RESOLVER_ip_get (h->external_address,
- AF_INET,
- GNUNET_TIME_UNIT_MINUTES,
- &process_external_ip,
- h);
-}
-
-
-/**
- * Add or remove UPnP-mapped addresses.
- *
- * @param cls the `struct GNUNET_NAT_Handle`
- * @param add_remove #GNUNET_YES to mean the new public IP address, #GNUNET_NO to mean
- * 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,
- 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;
- }
- else if (GNUNET_NO == add_remove)
- {
- /* 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);
- }
-}
-
-
-/**
- * Try to add a port mapping using UPnP.
- *
- * @param h overall NAT handle
- * @param port port to map with UPnP
- */
-static void
-add_minis (struct GNUNET_NAT_Handle *h,
- uint16_t port)
-{
- struct MiniList *ml;
-
- ml = h->mini_head;
- while (NULL != ml)
- {
- if (port == ml->port)
- 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);
-}
-
-
-/**
- * Task to add addresses from original bind to set of valid addrs.
- *
- * @param h the NAT handle
- */
-static void
-add_from_bind (struct GNUNET_NAT_Handle *h)
-{
- static struct in6_addr any = IN6ADDR_ANY_INIT;
-
- unsigned int i;
- struct sockaddr *sa;
- const struct sockaddr_in *v4;
-
- for (i = 0; i < h->num_local_addrs; i++)
- {
- sa = h->local_addrs[i];
- switch (sa->sa_family)
- {
- case AF_INET:
- if (sizeof (struct sockaddr_in) != h->local_addrlens[i])
- {
- GNUNET_break (0);
- break;
- }
- v4 = (const struct sockaddr_in *) sa;
- if (0 != v4->sin_addr.s_addr)
- 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])
- {
- GNUNET_break (0);
- break;
- }
- if (0 !=
- memcmp (&((const struct sockaddr_in6 *) sa)->sin6_addr,
- &any,
- sizeof (struct in6_addr)))
- add_to_address_list (h,
- LAL_BINDTO_ADDRESS,
- sa,
- sizeof (struct sockaddr_in6));
- break;
- default:
- break;
- }
- }
-}
-
-
-/**
- * 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
- * of the local host's addresses should the external port be mapped. The port
- * is taken from the corresponding sockaddr_in[6] field.
- *
- * @param cfg configuration to use
- * @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 @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 *
-GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg,
- int is_tcp,
- uint16_t adv_port,
- unsigned int num_addrs,
- const struct sockaddr **addrs,
- const socklen_t *addrlens,
- GNUNET_NAT_AddressCallback address_callback,
- GNUNET_NAT_ReversalCallback reversal_callback,
- void *callback_cls,
- struct GNUNET_NETWORK_Handle *sock)
-{
- struct GNUNET_NAT_Handle *h;
- struct in_addr in_addr;
- unsigned int i;
- char *binary;
-
- 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);
- h = GNUNET_new (struct GNUNET_NAT_Handle);
- h->server_retry_delay = GNUNET_TIME_UNIT_SECONDS;
- h->cfg = cfg;
- h->is_tcp = is_tcp;
- h->address_callback = address_callback;
- h->reversal_callback = reversal_callback;
- h->callback_cls = callback_cls;
- h->num_local_addrs = num_addrs;
- h->adv_port = adv_port;
- if (0 != num_addrs)
- {
- h->local_addrs = GNUNET_malloc (num_addrs * sizeof (struct sockaddr *));
- h->local_addrlens = GNUNET_malloc (num_addrs * sizeof (socklen_t));
- for (i = 0; i < num_addrs; i++)
- {
- GNUNET_assert (addrlens[i] > 0);
- GNUNET_assert (addrs[i] != NULL);
- h->local_addrlens[i] = addrlens[i];
- h->local_addrs[i] = GNUNET_malloc (addrlens[i]);
- GNUNET_memcpy (h->local_addrs[i], addrs[i], addrlens[i]);
- }
- }
- if (GNUNET_OK ==
- GNUNET_CONFIGURATION_have_value (cfg, "nat", "INTERNAL_ADDRESS"))
- {
- (void) GNUNET_CONFIGURATION_get_value_string (cfg, "nat",
- "INTERNAL_ADDRESS",
- &h->internal_address);
- }
- if ((h->internal_address != NULL) &&
- (inet_pton (AF_INET, h->internal_address, &in_addr) != 1))
- {
- GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
- "nat", "INTERNAL_ADDRESS",
- _("malformed"));
- GNUNET_free (h->internal_address);
- h->internal_address = NULL;
- }
-
- if (GNUNET_OK ==
- GNUNET_CONFIGURATION_have_value (cfg, "nat", "EXTERNAL_ADDRESS"))
- {
- (void) GNUNET_CONFIGURATION_get_value_string (cfg, "nat",
- "EXTERNAL_ADDRESS",
- &h->external_address);
- }
- h->behind_nat =
- GNUNET_CONFIGURATION_get_value_yesno (cfg, "nat", "BEHIND_NAT");
- h->nat_punched =
- GNUNET_CONFIGURATION_get_value_yesno (cfg, "nat", "PUNCHED_NAT");
- h->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_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");
-
- h->use_hostname =
- GNUNET_CONFIGURATION_get_value_yesno (cfg, "nat", "USE_HOSTNAME");
- h->disable_ipv6 =
- GNUNET_CONFIGURATION_get_value_yesno (cfg, "nat", "DISABLEV6");
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_time (cfg, "nat", "DYNDNS_FREQUENCY",
- &h->dyndns_frequency))
- h->dyndns_frequency = DYNDNS_FREQUENCY;
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_time (cfg, "nat", "IFC_SCAN_FREQUENCY",
- &h->ifc_scan_frequency))
- h->ifc_scan_frequency = IFC_SCAN_FREQUENCY;
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_time (cfg, "nat", "HOSTNAME_DNS_FREQUENCY",
- &h->hostname_dns_frequency))
- h->hostname_dns_frequency = HOSTNAME_DNS_FREQUENCY;
-
- 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) &&
- (GNUNET_YES == h->nat_punched))
- {
- 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
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "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)
- {
- char *stun_servers;
- size_t urls;
- ssize_t pos;
- size_t pos_port;
-
- h->socket = sock;
- stun_servers = NULL;
- /* Lets process the servers*/
- (void) GNUNET_CONFIGURATION_get_value_string (cfg,
- "nat",
- "STUN_SERVERS",
- &stun_servers);
- urls = 0;
- if ( (NULL != stun_servers) &&
- (strlen (stun_servers) > 0) )
- {
- pos_port = 0;
- for (pos = strlen (stun_servers) - 1;
- pos >= 0;
- pos--)
- {
- if (stun_servers[pos] == ':')
- {
- pos_port = pos + 1;
- stun_servers[pos] = '\0';
- continue;
- }
- if ((stun_servers[pos] == ' ') || (0 == pos))
- {
- struct StunServerList *ml;
-
- /* 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++;
- ml = GNUNET_new (struct StunServerList);
- ml->port = atoi (&stun_servers[pos_port]);
-
- /* 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:%i\n",
- ml->address,
- ml->port);
- GNUNET_CONTAINER_DLL_insert (h->stun_servers_head,
- h->stun_servers_tail,
- ml);
- stun_servers[pos] = '\0';
- }
- }
- }
- if (0 == urls)
- {
- 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);
- GNUNET_free_non_null (stun_servers);
- }
-
-
- /* Test for SUID binaries */
- binary = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-nat-server");
- if ( (GNUNET_YES == h->behind_nat) &&
- (GNUNET_YES == h->enable_nat_server) &&
- (GNUNET_YES !=
- GNUNET_OS_check_helper_binary (binary,
- GNUNET_YES,
- "-d 127.0.0.1" )))
- {
- // use localhost as source for that one udp-port, ok for testing
- h->enable_nat_server = GNUNET_NO;
- LOG (GNUNET_ERROR_TYPE_WARNING,
- _("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 (binary,
- GNUNET_YES,
- "-d 127.0.0.1 127.0.0.2 42"))) /* none of these parameters are actually used in privilege testing mode */
- {
- h->enable_nat_client = GNUNET_NO;
- LOG (GNUNET_ERROR_TYPE_WARNING,
- _("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 */
-
- if (NULL != h->address_callback)
- {
- 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);
- }
- add_from_bind (h);
-
- return h;
-}
-
-
-/**
- * Stop port redirection and public IP address detection for the given handle.
- * This frees the handle, after having sent the needed commands to close open ports.
- *
- * @param h the handle to stop
- */
-void
-GNUNET_NAT_unregister (struct GNUNET_NAT_Handle *h)
-{
- unsigned int i;
- struct LocalAddressList *lal;
- struct MiniList *ml;
- struct StunServerList *ssl;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "NAT unregister called\n");
- while (NULL != (ssl = h->stun_servers_head))
- {
- GNUNET_CONTAINER_DLL_remove (h->stun_servers_head,
- h->stun_servers_tail,
- ssl);
- GNUNET_free (ssl->address);
- GNUNET_free (ssl);
- }
- while (NULL != (lal = h->lal_head))
- {
- GNUNET_CONTAINER_DLL_remove (h->lal_head,
- h->lal_tail,
- lal);
- if (NULL != h->address_callback)
- h->address_callback (h->callback_cls,
- GNUNET_NO,
- (const struct sockaddr *) &lal[1],
- lal->addrlen);
- GNUNET_free (lal);
- }
- while (NULL != (ml = h->mini_head))
- {
- 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);
- }
- if (NULL != h->ext_dns)
- {
- GNUNET_RESOLVER_request_cancel (h->ext_dns);
- h->ext_dns = NULL;
- }
- if (NULL != h->hostname_dns)
- {
- GNUNET_RESOLVER_request_cancel (h->hostname_dns);
- h->hostname_dns = NULL;
- }
- if (NULL != h->server_read_task)
- {
- GNUNET_SCHEDULER_cancel (h->server_read_task);
- h->server_read_task = NULL;
- }
- if (NULL != h->ifc_task)
- {
- GNUNET_SCHEDULER_cancel (h->ifc_task);
- h->ifc_task = NULL;
- }
- if (NULL != h->hostname_task)
- {
- GNUNET_SCHEDULER_cancel (h->hostname_task);
- h->hostname_task = NULL;
- }
- if (NULL != h->dns_task)
- {
- GNUNET_SCHEDULER_cancel (h->dns_task);
- h->dns_task = NULL;
- }
- if (NULL != h->stun_task)
- {
- GNUNET_SCHEDULER_cancel (h->stun_task);
- h->stun_task = NULL;
- }
- if (NULL != h->stun_request)
- {
- GNUNET_NAT_stun_make_request_cancel (h->stun_request);
- h->stun_request = NULL;
- }
- if (NULL != h->server_proc)
- {
- 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;
- }
- if (NULL != h->server_stdout)
- {
- GNUNET_DISK_pipe_close (h->server_stdout);
- h->server_stdout = NULL;
- h->server_stdout_handle = NULL;
- }
- for (i = 0; i < h->num_local_addrs; i++)
- GNUNET_free (h->local_addrs[i]);
- GNUNET_free_non_null (h->local_addrs);
- GNUNET_free_non_null (h->local_addrlens);
- GNUNET_free_non_null (h->external_address);
- GNUNET_free_non_null (h->internal_address);
- GNUNET_free (h);
-}
-
-
-/**
- * We learned about a peer (possibly behind NAT) so run the
- * gnunet-helper-nat-client to send dummy ICMP responses to cause
- * that peer to connect to us (connection reversal).
- *
- * @param h handle (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
- */
-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 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 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 GNUNET_SYSERR;
- }
- GNUNET_snprintf (port_as_string,
- sizeof (port_as_string),
- "%d",
- h->adv_port);
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- _("Running gnunet-helper-nat-client %s %s %u\n"),
- h->internal_address,
- inet4,
- (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, NULL,
- binary,
- "gnunet-helper-nat-client",
- h->internal_address,
- inet4, port_as_string, NULL);
- GNUNET_free (binary);
- if (NULL == proc)
- return GNUNET_SYSERR;
- /* we know that the gnunet-helper-nat-client will terminate virtually
- * instantly */
- GNUNET_OS_process_wait (proc);
- GNUNET_OS_process_destroy (proc);
- return GNUNET_OK;
-}
-
-
-/**
- * Test if the given address is (currently) a plausible IP address for this peer.
- *
- * @param h the handle returned by register
- * @param addr IP address to test (IPv4 or IPv6)
- * @param addrlen number of bytes in @a addr
- * @return #GNUNET_YES if the address is plausible,
- * #GNUNET_NO if the address is not plausible,
- * #GNUNET_SYSERR if the address is malformed
- */
-int
-GNUNET_NAT_test_address (struct GNUNET_NAT_Handle *h,
- const void *addr,
- socklen_t addrlen)
-{
- struct LocalAddressList *pos;
- const struct sockaddr_in *in4;
- const struct sockaddr_in6 *in6;
- char pbuf[INET6_ADDRSTRLEN+1];
-
- if ((addrlen != sizeof (struct in_addr)) &&
- (addrlen != sizeof (struct in6_addr)))
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- for (pos = h->lal_head; NULL != pos; pos = pos->next)
- {
- if (pos->addrlen == sizeof (struct sockaddr_in))
- {
- in4 = (struct sockaddr_in *) &pos[1];
- if ((addrlen == sizeof (struct in_addr)) &&
- (0 == memcmp (&in4->sin_addr, addr, sizeof (struct in_addr))))
- return GNUNET_YES;
- }
- else if (pos->addrlen == sizeof (struct sockaddr_in6))
- {
- in6 = (struct sockaddr_in6 *) &pos[1];
- if ((addrlen == sizeof (struct in6_addr)) &&
- (0 == memcmp (&in6->sin6_addr, addr, sizeof (struct in6_addr))))
- return GNUNET_YES;
- }
- else
- {
- GNUNET_assert (0);
- }
- }
- LOG (GNUNET_ERROR_TYPE_WARNING,
- "Asked to validate one of my addresses (%s) and validation failed!\n",
- inet_ntop ((addrlen == sizeof(struct in_addr))
- ? AF_INET
- : AF_INET6,
- addr,
- pbuf, sizeof (pbuf)));
- 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 */
diff --git a/src/nat/nat_mini.c b/src/nat/nat_mini.c
deleted file mode 100644
index 915bcbdb6..000000000
--- a/src/nat/nat_mini.c
+++ /dev/null
@@ -1,712 +0,0 @@
-/*
- This file is part of GNUnet.
- Copyright (C) 2011-2014 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_mini.c
- * @brief functions for interaction with miniupnp; tested with miniupnpc 1.5
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include "gnunet_util_lib.h"
-#include "gnunet_nat_lib.h"
-#include "nat.h"
-
-#define LOG(kind,...) GNUNET_log_from (kind, "nat", __VA_ARGS__)
-
-/**
- * How long do we give upnpc to create a mapping?
- */
-#define MAP_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15)
-
-/**
- * How long do we give upnpc to remove a mapping?
- */
-#define UNMAP_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1)
-
-/**
- * How often do we check for changes in the mapping?
- */
-#define MAP_REFRESH_FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
-
-
-
-/**
- * Opaque handle to cancel "GNUNET_NAT_mini_get_external_ipv4" operation.
- */
-struct GNUNET_NAT_ExternalHandle
-{
-
- /**
- * Function to call with the result.
- */
- GNUNET_NAT_IPCallback cb;
-
- /**
- * Closure for @e cb.
- */
- void *cb_cls;
-
- /**
- * Read task.
- */
- struct GNUNET_SCHEDULER_Task * task;
-
- /**
- * Handle to 'external-ip' process.
- */
- struct GNUNET_OS_Process *eip;
-
- /**
- * Handle to stdout pipe of 'external-ip'.
- */
- struct GNUNET_DISK_PipeHandle *opipe;
-
- /**
- * Read handle of @e opipe.
- */
- const struct GNUNET_DISK_FileHandle *r;
-
- /**
- * When should this operation time out?
- */
- struct GNUNET_TIME_Absolute timeout;
-
- /**
- * Number of bytes in 'buf' that are valid.
- */
- size_t off;
-
- /**
- * Destination of our read operation (output of 'external-ip').
- */
- char buf[17];
-
- /**
- * Error code for better debugging and user feedback
- */
- enum GNUNET_NAT_StatusCode ret;
-};
-
-
-/**
- * Read the output of 'external-ip' into buf. When complete, parse the
- * address and call our callback.
- *
- * @param cls the `struct GNUNET_NAT_ExternalHandle`
- */
-static void
-read_external_ipv4 (void *cls)
-{
- struct GNUNET_NAT_ExternalHandle *eh = cls;
- ssize_t ret;
- struct in_addr addr;
- const struct GNUNET_SCHEDULER_TaskContext *tc;
-
- eh->task = NULL;
- tc = GNUNET_SCHEDULER_get_task_context ();
- if (GNUNET_YES ==
- GNUNET_NETWORK_fdset_handle_isset (tc->read_ready, eh->r))
- {
- ret =
- GNUNET_DISK_file_read (eh->r, &eh->buf[eh->off],
- sizeof (eh->buf) - eh->off);
- }
- else
- {
- eh->ret = GNUNET_NAT_ERROR_IPC_FAILURE;
- ret = -1; /* error reading, timeout, etc. */
- }
- if (ret > 0)
- {
- /* try to read more */
- eh->off += ret;
- eh->task =
- GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_absolute_get_remaining
- (eh->timeout), eh->r,
- &read_external_ipv4, eh);
- return;
- }
- eh->ret = GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_OUTPUT_INVALID;
- if ((eh->off > 7) && (eh->buf[eh->off - 1] == '\n'))
- {
- eh->buf[eh->off - 1] = '\0';
- if (1 == inet_pton (AF_INET, eh->buf, &addr))
- {
- if (0 != addr.s_addr)
- eh->ret = GNUNET_NAT_ERROR_EXTERNAL_IP_ADDRESS_INVALID; /* got 0.0.0.0 */
- else
- eh->ret = GNUNET_NAT_ERROR_SUCCESS;
- }
- }
- eh->cb (eh->cb_cls,
- (GNUNET_NAT_ERROR_SUCCESS == eh->ret) ? &addr : NULL,
- eh->ret);
- GNUNET_NAT_mini_get_external_ipv4_cancel (eh);
-}
-
-
-/**
- * (Asynchronously) signal error invoking "external-ip" to client.
- *
- * @param cls the `struct GNUNET_NAT_ExternalHandle` (freed)
- */
-static void
-signal_external_ip_error (void *cls)
-{
- struct GNUNET_NAT_ExternalHandle *eh = cls;
-
- eh->task = NULL;
- eh->cb (eh->cb_cls,
- NULL,
- eh->ret);
- GNUNET_free (eh);
-}
-
-
-/**
- * Try to get the external IPv4 address of this peer.
- *
- * @param timeout when to fail
- * @param cb function to call with result
- * @param cb_cls closure for @a cb
- * @return handle for cancellation (can only be used until @a cb is called), never NULL
- */
-struct GNUNET_NAT_ExternalHandle *
-GNUNET_NAT_mini_get_external_ipv4 (struct GNUNET_TIME_Relative timeout,
- GNUNET_NAT_IPCallback cb, void *cb_cls)
-{
- struct GNUNET_NAT_ExternalHandle *eh;
-
- eh = GNUNET_new (struct GNUNET_NAT_ExternalHandle);
- eh->cb = cb;
- eh->cb_cls = cb_cls;
- eh->ret = GNUNET_NAT_ERROR_SUCCESS;
- if (GNUNET_SYSERR ==
- GNUNET_OS_check_helper_binary ("external-ip", GNUNET_NO, NULL))
- {
- LOG (GNUNET_ERROR_TYPE_INFO,
- _("`external-ip' command not found\n"));
- eh->ret = GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_NOT_FOUND;
- eh->task = GNUNET_SCHEDULER_add_now (&signal_external_ip_error,
- eh);
- return eh;
- }
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Running `external-ip' to determine our external IP\n");
- eh->opipe = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES);
- if (NULL == eh->opipe)
- {
- eh->ret = GNUNET_NAT_ERROR_IPC_FAILURE;
- eh->task = GNUNET_SCHEDULER_add_now (&signal_external_ip_error,
- eh);
- return eh;
- }
- eh->eip =
- GNUNET_OS_start_process (GNUNET_NO, 0, NULL, eh->opipe, NULL,
- "external-ip", "external-ip",
- NULL);
- if (NULL == eh->eip)
- {
- GNUNET_DISK_pipe_close (eh->opipe);
- eh->ret = GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_FAILED;
- eh->task = GNUNET_SCHEDULER_add_now (&signal_external_ip_error,
- eh);
- return eh;
- }
- GNUNET_DISK_pipe_close_end (eh->opipe, GNUNET_DISK_PIPE_END_WRITE);
- eh->timeout = GNUNET_TIME_relative_to_absolute (timeout);
- eh->r = GNUNET_DISK_pipe_handle (eh->opipe, GNUNET_DISK_PIPE_END_READ);
- eh->task =
- GNUNET_SCHEDULER_add_read_file (timeout,
- eh->r,
- &read_external_ipv4, eh);
- return eh;
-}
-
-
-/**
- * Cancel operation.
- *
- * @param eh operation to cancel
- */
-void
-GNUNET_NAT_mini_get_external_ipv4_cancel (struct GNUNET_NAT_ExternalHandle *eh)
-{
- if (NULL != eh->eip)
- {
- (void) GNUNET_OS_process_kill (eh->eip, SIGKILL);
- GNUNET_OS_process_destroy (eh->eip);
- }
- if (NULL != eh->opipe)
- GNUNET_DISK_pipe_close (eh->opipe);
- if (NULL != eh->task)
- GNUNET_SCHEDULER_cancel (eh->task);
- GNUNET_free (eh);
-}
-
-
-/**
- * Handle to a mapping created with upnpc.
- */
-struct GNUNET_NAT_MiniHandle
-{
-
- /**
- * Function to call on mapping changes.
- */
- GNUNET_NAT_MiniAddressCallback ac;
-
- /**
- * Closure for @e ac.
- */
- void *ac_cls;
-
- /**
- * Command used to install the map.
- */
- struct GNUNET_OS_CommandHandle *map_cmd;
-
- /**
- * Command used to refresh our map information.
- */
- struct GNUNET_OS_CommandHandle *refresh_cmd;
-
- /**
- * Command used to remove the mapping.
- */
- struct GNUNET_OS_CommandHandle *unmap_cmd;
-
- /**
- * Our current external mapping (if we have one).
- */
- struct sockaddr_in current_addr;
-
- /**
- * We check the mapping periodically to see if it
- * still works. This task triggers the check.
- */
- struct GNUNET_SCHEDULER_Task * refresh_task;
-
- /**
- * Are we mapping TCP or UDP?
- */
- int is_tcp;
-
- /**
- * Did we succeed with creating a mapping?
- */
- int did_map;
-
- /**
- * Did we find our mapping during refresh scan?
- */
- int found;
-
- /**
- * Which port are we mapping?
- */
- uint16_t port;
-
-};
-
-
-/**
- * Run "upnpc -l" to find out if our mapping changed.
- *
- * @param cls the `struct GNUNET_NAT_MiniHandle`
- */
-static void
-do_refresh (void *cls);
-
-
-/**
- * Process the output from the "upnpc -r" command.
- *
- * @param cls the `struct GNUNET_NAT_MiniHandle`
- * @param line line of output, NULL at the end
- */
-static void
-process_map_output (void *cls, const char *line);
-
-
-/**
- * Run "upnpc -r" to map our internal port.
- *
- * @param mini our handle
- */
-static void
-run_upnpc_r (struct GNUNET_NAT_MiniHandle *mini)
-{
- char pstr[6];
-
- GNUNET_snprintf (pstr,
- sizeof (pstr),
- "%u",
- (unsigned int) mini->port);
- mini->map_cmd =
- GNUNET_OS_command_run (&process_map_output, mini, MAP_TIMEOUT,
- "upnpc", "upnpc", "-r", pstr,
- mini->is_tcp ? "tcp" : "udp", NULL);
- if (NULL == mini->map_cmd)
- {
- mini->ac (mini->ac_cls,
- GNUNET_SYSERR,
- NULL, 0,
- GNUNET_NAT_ERROR_UPNPC_FAILED);
- return;
- }
-}
-
-
-/**
- * Process the output from "upnpc -l" to see if our
- * external mapping changed. If so, do the notifications.
- *
- * @param cls the `struct GNUNET_NAT_MiniHandle`
- * @param line line of output, NULL at the end
- */
-static void
-process_refresh_output (void *cls, const char *line)
-{
- struct GNUNET_NAT_MiniHandle *mini = cls;
- char pstr[9];
- const char *s;
- unsigned int nport;
- struct in_addr exip;
-
- if (NULL == line)
- {
- GNUNET_OS_command_stop (mini->refresh_cmd);
- mini->refresh_cmd = NULL;
- if (GNUNET_NO == mini->found)
- {
- /* mapping disappeared, try to re-create */
- if (GNUNET_YES == mini->did_map)
- {
- mini->ac (mini->ac_cls,
- GNUNET_NO,
- (const struct sockaddr *) &mini->current_addr,
- sizeof (mini->current_addr),
- GNUNET_NAT_ERROR_SUCCESS);
- mini->did_map = GNUNET_NO;
- }
- run_upnpc_r (mini);
- }
- return;
- }
- if (!mini->did_map)
- return; /* never mapped, won't find our mapping anyway */
-
- /* we're looking for output of the form:
- * "ExternalIPAddress = 12.134.41.124" */
-
- s = strstr (line, "ExternalIPAddress = ");
- if (NULL != s)
- {
- s += strlen ("ExternalIPAddress = ");
- if (1 != inet_pton (AF_INET, s, &exip))
- return; /* skip */
- if (exip.s_addr == mini->current_addr.sin_addr.s_addr)
- return; /* no change */
- /* update mapping */
- mini->ac (mini->ac_cls, GNUNET_NO,
- (const struct sockaddr *) &mini->current_addr,
- sizeof (mini->current_addr),
- GNUNET_NAT_ERROR_SUCCESS);
- mini->current_addr.sin_addr = exip;
- mini->ac (mini->ac_cls, GNUNET_YES,
- (const struct sockaddr *) &mini->current_addr,
- sizeof (mini->current_addr),
- GNUNET_NAT_ERROR_SUCCESS);
- return;
- }
- /*
- * we're looking for output of the form:
- *
- * "0 TCP 3000->192.168.2.150:3000 'libminiupnpc' ''"
- * "1 UDP 3001->192.168.2.150:3001 'libminiupnpc' ''"
- *
- * the pattern we look for is:
- *
- * "%s TCP PORT->STRING:OURPORT *" or
- * "%s UDP PORT->STRING:OURPORT *"
- */
- GNUNET_snprintf (pstr, sizeof (pstr), ":%u ", mini->port);
- if (NULL == (s = strstr (line, "->")))
- return; /* skip */
- if (NULL == strstr (s, pstr))
- return; /* skip */
- if (1 !=
- SSCANF (line,
- (mini->is_tcp) ? "%*u TCP %u->%*s:%*u %*s" :
- "%*u UDP %u->%*s:%*u %*s", &nport))
- return; /* skip */
- mini->found = GNUNET_YES;
- if (nport == ntohs (mini->current_addr.sin_port))
- return; /* no change */
-
- /* external port changed, update mapping */
- mini->ac (mini->ac_cls, GNUNET_NO,
- (const struct sockaddr *) &mini->current_addr,
- sizeof (mini->current_addr),
- GNUNET_NAT_ERROR_SUCCESS);
- mini->current_addr.sin_port = htons ((uint16_t) nport);
- mini->ac (mini->ac_cls, GNUNET_YES,
- (const struct sockaddr *) &mini->current_addr,
- sizeof (mini->current_addr),
- GNUNET_NAT_ERROR_SUCCESS);
-}
-
-
-/**
- * Run "upnpc -l" to find out if our mapping changed.
- *
- * @param cls the 'struct GNUNET_NAT_MiniHandle'
- */
-static void
-do_refresh (void *cls)
-{
- struct GNUNET_NAT_MiniHandle *mini = cls;
- int ac;
-
- mini->refresh_task =
- GNUNET_SCHEDULER_add_delayed (MAP_REFRESH_FREQ,
- &do_refresh, mini);
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Running `upnpc' to check if our mapping still exists\n");
- mini->found = GNUNET_NO;
- ac = GNUNET_NO;
- if (NULL != mini->map_cmd)
- {
- /* took way too long, abort it! */
- GNUNET_OS_command_stop (mini->map_cmd);
- mini->map_cmd = NULL;
- ac = GNUNET_YES;
- }
- if (NULL != mini->refresh_cmd)
- {
- /* took way too long, abort it! */
- GNUNET_OS_command_stop (mini->refresh_cmd);
- mini->refresh_cmd = NULL;
- ac = GNUNET_YES;
- }
- mini->refresh_cmd =
- GNUNET_OS_command_run (&process_refresh_output, mini, MAP_TIMEOUT,
- "upnpc", "upnpc", "-l", NULL);
- if (GNUNET_YES == ac)
- mini->ac (mini->ac_cls,
- GNUNET_SYSERR,
- NULL, 0,
- GNUNET_NAT_ERROR_UPNPC_TIMEOUT);
-}
-
-
-/**
- * Process the output from the 'upnpc -r' command.
- *
- * @param cls the `struct GNUNET_NAT_MiniHandle`
- * @param line line of output, NULL at the end
- */
-static void
-process_map_output (void *cls,
- const char *line)
-{
- struct GNUNET_NAT_MiniHandle *mini = cls;
- const char *ipaddr;
- char *ipa;
- const char *pstr;
- unsigned int port;
-
- if (NULL == line)
- {
- GNUNET_OS_command_stop (mini->map_cmd);
- mini->map_cmd = NULL;
- if (GNUNET_YES != mini->did_map)
- mini->ac (mini->ac_cls,
- GNUNET_SYSERR,
- NULL, 0,
- GNUNET_NAT_ERROR_UPNPC_PORTMAP_FAILED);
- if (NULL == mini->refresh_task)
- mini->refresh_task =
- GNUNET_SCHEDULER_add_delayed (MAP_REFRESH_FREQ,
- &do_refresh,
- mini);
- return;
- }
- /*
- * The upnpc output we're after looks like this:
- *
- * "external 87.123.42.204:3000 TCP is redirected to internal 192.168.2.150:3000"
- */
- if ((NULL == (ipaddr = strstr (line, " "))) ||
- (NULL == (pstr = strstr (ipaddr, ":"))) ||
- (1 != SSCANF (pstr + 1, "%u", &port)))
- {
- return; /* skip line */
- }
- ipa = GNUNET_strdup (ipaddr + 1);
- strstr (ipa, ":")[0] = '\0';
- if (1 != inet_pton (AF_INET, ipa, &mini->current_addr.sin_addr))
- {
- GNUNET_free (ipa);
- return; /* skip line */
- }
- GNUNET_free (ipa);
-
- mini->current_addr.sin_port = htons (port);
- mini->current_addr.sin_family = AF_INET;
-#if HAVE_SOCKADDR_IN_SIN_LEN
- mini->current_addr.sin_len = sizeof (struct sockaddr_in);
-#endif
- mini->did_map = GNUNET_YES;
- mini->ac (mini->ac_cls, GNUNET_YES,
- (const struct sockaddr *) &mini->current_addr,
- sizeof (mini->current_addr),
- GNUNET_NAT_ERROR_SUCCESS);
-}
-
-
-/**
- * Start mapping the given port using (mini)upnpc. This function
- * should typically not be used directly (it is used within the
- * general-purpose #GNUNET_NAT_register() code). However, it can be
- * used if specifically UPnP-based NAT traversal is to be used or
- * tested.
- *
- * @param port port to map
- * @param is_tcp #GNUNET_YES to map TCP, #GNUNET_NO for UDP
- * @param ac function to call with mapping result
- * @param ac_cls closure for @a ac
- * @return NULL on error (no 'upnpc' installed)
- */
-struct GNUNET_NAT_MiniHandle *
-GNUNET_NAT_mini_map_start (uint16_t port,
- int is_tcp,
- GNUNET_NAT_MiniAddressCallback ac,
- void *ac_cls)
-{
- struct GNUNET_NAT_MiniHandle *ret;
-
- if (GNUNET_SYSERR ==
- GNUNET_OS_check_helper_binary ("upnpc", GNUNET_NO, NULL))
- {
- LOG (GNUNET_ERROR_TYPE_INFO,
- _("`upnpc' command not found\n"));
- ac (ac_cls,
- GNUNET_SYSERR,
- NULL, 0,
- GNUNET_NAT_ERROR_UPNPC_NOT_FOUND);
- return NULL;
- }
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Running `upnpc' to install mapping\n");
- ret = GNUNET_new (struct GNUNET_NAT_MiniHandle);
- ret->ac = ac;
- ret->ac_cls = ac_cls;
- ret->is_tcp = is_tcp;
- ret->port = port;
- ret->refresh_task =
- GNUNET_SCHEDULER_add_delayed (MAP_REFRESH_FREQ,
- &do_refresh,
- ret);
- run_upnpc_r (ret);
- return ret;
-}
-
-
-/**
- * Process output from our 'unmap' command.
- *
- * @param cls the `struct GNUNET_NAT_MiniHandle`
- * @param line line of output, NULL at the end
- */
-static void
-process_unmap_output (void *cls, const char *line)
-{
- struct GNUNET_NAT_MiniHandle *mini = cls;
-
- if (NULL == line)
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "UPnP unmap done\n");
- GNUNET_OS_command_stop (mini->unmap_cmd);
- mini->unmap_cmd = NULL;
- GNUNET_free (mini);
- return;
- }
- /* we don't really care about the output... */
-}
-
-
-/**
- * Remove a mapping created with (mini)upnpc. Calling
- * this function will give 'upnpc' 1s to remove tha mapping,
- * so while this function is non-blocking, a task will be
- * left with the scheduler for up to 1s past this call.
- *
- * @param mini the handle
- */
-void
-GNUNET_NAT_mini_map_stop (struct GNUNET_NAT_MiniHandle *mini)
-{
- char pstr[6];
-
- if (NULL != mini->refresh_task)
- {
- GNUNET_SCHEDULER_cancel (mini->refresh_task);
- mini->refresh_task = NULL;
- }
- if (NULL != mini->refresh_cmd)
- {
- GNUNET_OS_command_stop (mini->refresh_cmd);
- mini->refresh_cmd = NULL;
- }
- if (NULL != mini->map_cmd)
- {
- GNUNET_OS_command_stop (mini->map_cmd);
- mini->map_cmd = NULL;
- }
- if (GNUNET_NO == mini->did_map)
- {
- GNUNET_free (mini);
- return;
- }
- mini->ac (mini->ac_cls, GNUNET_NO,
- (const struct sockaddr *) &mini->current_addr,
- sizeof (mini->current_addr),
- GNUNET_NAT_ERROR_SUCCESS);
- /* Note: oddly enough, deletion uses the external port whereas
- * addition uses the internal port; this rarely matters since they
- * often are the same, but it might... */
- GNUNET_snprintf (pstr,
- sizeof (pstr),
- "%u",
- (unsigned int) ntohs (mini->current_addr.sin_port));
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Unmapping port %u with UPnP\n",
- ntohs (mini->current_addr.sin_port));
- mini->unmap_cmd =
- GNUNET_OS_command_run (&process_unmap_output, mini, UNMAP_TIMEOUT,
- "upnpc", "upnpc", "-d", pstr,
- mini->is_tcp ? "tcp" : "udp", NULL);
-}
-
-
-/* end of nat_mini.c */
diff --git a/src/nat/nat_stun.c b/src/nat/nat_stun.c
deleted file mode 100644
index 62916ab84..000000000
--- a/src/nat/nat_stun.c
+++ /dev/null
@@ -1,439 +0,0 @@
-/*
- This file is part of GNUnet.
- Copyright (C) 2009, 2015 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.
-*/
-/**
- * This code provides some support for doing STUN transactions.
- * We send simplest possible packet ia REQUEST with BIND to a STUN server.
- *
- * All STUN packets start with a simple header made of a type,
- * length (excluding the header) and a 16-byte random transaction id.
- * Following the header we may have zero or more attributes, each
- * structured as a type, length and a value (whose format depends
- * on the type, but often contains addresses).
- * Of course all fields are in network format.
- *
- * This code was based on ministun.c.
- *
- * @file nat/nat_stun.c
- * @brief Functions for STUN functionality
- * @author Bruno Souza Cabral
- */
-
-#include "platform.h"
-#include "gnunet_util_lib.h"
-#include "gnunet_resolver_service.h"
-#include "gnunet_nat_lib.h"
-
-
-#include "nat_stun.h"
-
-#define LOG(kind,...) GNUNET_log_from (kind, "stun", __VA_ARGS__)
-
-#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15)
-
-
-/**
- * Handle to a request given to the resolver. Can be used to cancel
- * the request prior to the timeout or successful execution. Also
- * used to track our internal state for the request.
- */
-struct GNUNET_NAT_STUN_Handle
-{
-
- /**
- * Handle to a pending DNS lookup request.
- */
- struct GNUNET_RESOLVER_RequestHandle *dns_active;
-
- /**
- * Handle to the listen socket
- */
- struct GNUNET_NETWORK_Handle *sock;
-
- /**
- * Stun server address
- */
- char *stun_server;
-
- /**
- * Function to call when a error occours
- */
- GNUNET_NAT_STUN_ErrorCallback cb;
-
- /**
- * Closure for @e cb.
- */
- void *cb_cls;
-
- /**
- * Do we got a DNS resolution successfully?
- */
- int dns_success;
-
- /**
- * STUN port
- */
- uint16_t stun_port;
-
-};
-
-
-/**
- * here we store credentials extracted from a message
-*/
-struct StunState
-{
- uint16_t attr;
-};
-
-
-/**
- * Encode a class and method to a compatible STUN format
- *
- * @param msg_class class to be converted
- * @param method method to be converted
- * @return message in a STUN compatible format
- */
-static int
-encode_message (enum StunClasses msg_class,
- enum StunMethods method)
-{
- return ((msg_class & 1) << 4) | ((msg_class & 2) << 7) |
- (method & 0x000f) | ((method & 0x0070) << 1) | ((method & 0x0f800) << 2);
-}
-
-
-/**
- * Fill the stun_header with a random request_id
- *
- * @param req, stun header to be filled
- */
-static void
-generate_request_id (struct stun_header *req)
-{
- unsigned int x;
-
- req->magic = htonl(STUN_MAGIC_COOKIE);
- for (x = 0; x < 3; x++)
- req->id.id[x] = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
- UINT32_MAX);
-}
-
-
-/**
- * Extract the STUN_MAPPED_ADDRESS from the stun response.
- * This is used as a callback for stun_handle_response
- * when called from stun_request.
- *
- * @param st, pointer where we will set the type
- * @param attr , received stun attribute
- * @param arg , pointer to a sockaddr_in where we will set the reported IP and port
- * @param magic , Magic cookie
- *
- * @return 0 on success, other value otherwise
- */
-static int
-stun_get_mapped (struct StunState *st,
- struct stun_attr *attr,
- struct sockaddr_in *arg,
- unsigned int magic)
-{
- struct stun_addr *returned_addr = (struct stun_addr *)(attr + 1);
- struct sockaddr_in *sa = (struct sockaddr_in *)arg;
- unsigned short type = ntohs(attr->attr);
-
- switch (type)
- {
- case STUN_MAPPED_ADDRESS:
- if (st->attr == STUN_XOR_MAPPED_ADDRESS ||
- st->attr == STUN_MS_XOR_MAPPED_ADDRESS)
- return 1;
- magic = 0;
- break;
- case STUN_MS_XOR_MAPPED_ADDRESS:
- if (st->attr == STUN_XOR_MAPPED_ADDRESS)
- return 1;
- break;
- case STUN_XOR_MAPPED_ADDRESS:
- break;
- default:
- return 1;
- }
- if ( (ntohs(attr->len) < 8) &&
- (returned_addr->family != 1) )
- {
- return 1;
- }
- st->attr = type;
- sa->sin_family = AF_INET;
- sa->sin_port = returned_addr->port ^ htons(ntohl(magic) >> 16);
- sa->sin_addr.s_addr = returned_addr->addr ^ magic;
- return 0;
-}
-
-
-/**
- * Handle an incoming STUN message, Do some basic sanity checks on packet size and content,
- * try to extract a bit of information, and possibly reply.
- * At the moment this only processes BIND requests, and returns
- * the externally visible address of the request.
- * If a callback is specified, invoke it with the attribute.
- *
- * @param data the packet
- * @param len the length of the packet in @a data
- * @param[out] arg sockaddr_in where we will set our discovered address
- *
- * @return, #GNUNET_OK on OK, #GNUNET_NO if the packet is invalid (not a stun packet)
- */
-int
-GNUNET_NAT_stun_handle_packet (const void *data,
- size_t len,
- struct sockaddr_in *arg)
-{
- const struct stun_header *hdr = (const struct stun_header *)data;
- struct stun_attr *attr;
- struct StunState st;
- int ret = GNUNET_OK;
- uint32_t advertised_message_size;
- uint32_t message_magic_cookie;
-
- /* On entry, 'len' is the length of the udp payload. After the
- * initial checks it becomes the size of unprocessed options,
- * while 'data' is advanced accordingly.
- */
- if (len < sizeof(struct stun_header))
- {
- LOG (GNUNET_ERROR_TYPE_INFO,
- "STUN packet too short (only %d, wanting at least %d)\n",
- (int) len,
- (int) sizeof(struct stun_header));
- GNUNET_break_op (0);
- return GNUNET_NO;
- }
- /* Skip header as it is already in hdr */
- len -= sizeof(struct stun_header);
- data += sizeof(struct stun_header);
-
- /* len as advertised in the message */
- advertised_message_size = ntohs(hdr->msglen);
-
- message_magic_cookie = ntohl(hdr->magic);
- /* Compare if the cookie match */
- if (STUN_MAGIC_COOKIE != message_magic_cookie)
- {
- LOG (GNUNET_ERROR_TYPE_INFO,
- "Invalid magic cookie \n");
- return GNUNET_NO;
- }
-
- LOG (GNUNET_ERROR_TYPE_INFO,
- "STUN Packet, msg %s (%04x), length: %d\n",
- stun_msg2str(ntohs(hdr->msgtype)),
- ntohs(hdr->msgtype),
- advertised_message_size);
- if (advertised_message_size > len)
- {
- LOG (GNUNET_ERROR_TYPE_INFO,
- "Scrambled STUN packet length (got %d, expecting %d)\n",
- advertised_message_size,
- (int)len);
- return GNUNET_NO;
- }
- len = advertised_message_size;
- memset (&st, 0, sizeof(st));
-
- while (len > 0)
- {
- if (len < sizeof(struct stun_attr))
- {
- LOG (GNUNET_ERROR_TYPE_INFO,
- "Attribute too short (got %d, expecting %d)\n",
- (int)len,
- (int) sizeof(struct stun_attr));
- break;
- }
- attr = (struct stun_attr *)data;
-
- /* compute total attribute length */
- advertised_message_size = ntohs(attr->len) + sizeof(struct stun_attr);
-
- /* Check if we still have space in our buffer */
- if (advertised_message_size > len )
- {
- LOG (GNUNET_ERROR_TYPE_INFO,
- "Inconsistent Attribute (length %d exceeds remaining msg len %d)\n",
- advertised_message_size,
- (int)len);
- break;
- }
- stun_get_mapped (&st,
- attr,
- arg,
- hdr->magic);
- /* Clear attribute id: in case previous entry was a string,
- * this will act as the terminator for the string.
- */
- attr->attr = 0;
- data += advertised_message_size;
- len -= advertised_message_size;
- ret = GNUNET_OK;
- }
- return ret;
-}
-
-
-/**
- * Cancel active STUN request. Frees associated resources
- * and ensures that the callback is no longer invoked.
- *
- * @param rh request to cancel
- */
-void
-GNUNET_NAT_stun_make_request_cancel (struct GNUNET_NAT_STUN_Handle *rh)
-{
- if (NULL != rh->dns_active)
- {
- GNUNET_RESOLVER_request_cancel (rh->dns_active);
- rh->dns_active = NULL;
- }
- GNUNET_free (rh->stun_server);
- GNUNET_free (rh);
-}
-
-
-/**
- * Try to establish a connection given the specified address.
- *
- * @param cls our `struct GNUNET_NAT_STUN_Handle *`
- * @param addr address to try, NULL for "last call"
- * @param addrlen length of @a addr
- */
-static void
-stun_dns_callback (void *cls,
- const struct sockaddr *addr,
- socklen_t addrlen)
-{
- struct GNUNET_NAT_STUN_Handle *rh = cls;
- struct stun_header *req;
- uint8_t reqdata[1024];
- int reqlen;
- struct sockaddr_in server;
-
- if (NULL == addr)
- {
- rh->dns_active = NULL;
- if (GNUNET_NO == rh->dns_success)
- {
- LOG (GNUNET_ERROR_TYPE_INFO,
- "Error resolving host %s\n",
- rh->stun_server);
- rh->cb (rh->cb_cls,
- GNUNET_NAT_ERROR_NOT_ONLINE);
- }
- else if (GNUNET_SYSERR == rh->dns_success)
- {
- rh->cb (rh->cb_cls,
- GNUNET_NAT_ERROR_INTERNAL_NETWORK_ERROR);
- }
- else
- {
- rh->cb (rh->cb_cls,
- GNUNET_NAT_ERROR_SUCCESS);
- }
- GNUNET_NAT_stun_make_request_cancel (rh);
- return;
- }
-
- rh->dns_success = GNUNET_YES;
- memset (&server,0, sizeof(server));
- server.sin_family = AF_INET;
- server.sin_addr = ((struct sockaddr_in *)addr)->sin_addr;
- server.sin_port = htons(rh->stun_port);
-#if HAVE_SOCKADDR_IN_SIN_LEN
- server.sin_len = (u_char) sizeof (struct sockaddr_in);
-#endif
-
- /*Craft the simplest possible STUN packet. A request binding*/
- req = (struct stun_header *)reqdata;
- generate_request_id (req);
- reqlen = 0;
- req->msgtype = 0;
- req->msglen = 0;
- req->msglen = htons (reqlen);
- req->msgtype = htons (encode_message (STUN_REQUEST,
- STUN_BINDING));
-
- /* Send the packet */
- if (-1 ==
- GNUNET_NETWORK_socket_sendto (rh->sock,
- req,
- ntohs(req->msglen) + sizeof(*req),
- (const struct sockaddr *) &server,
- sizeof (server)))
- {
- GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
- "sendto");
- rh->dns_success = GNUNET_SYSERR;
- return;
- }
-}
-
-
-/**
- * Make Generic STUN request. Sends a generic stun request to the
- * server specified using the specified socket, possibly waiting for
- * a reply and filling the 'reply' field with the externally visible
- * address.
- *
- * @param server the address of the stun server
- * @param port port of the stun server
- * @param sock the socket used to send the request
- * @param cb callback in case of error
- * @param cb_cls closure for @a cb
- * @return NULL on error
- */
-struct GNUNET_NAT_STUN_Handle *
-GNUNET_NAT_stun_make_request (const char *server,
- uint16_t port,
- struct GNUNET_NETWORK_Handle *sock,
- GNUNET_NAT_STUN_ErrorCallback cb,
- void *cb_cls)
-{
- struct GNUNET_NAT_STUN_Handle *rh;
-
- rh = GNUNET_new (struct GNUNET_NAT_STUN_Handle);
- rh->sock = sock;
- rh->cb = cb;
- rh->cb_cls = cb_cls;
- rh->stun_server = GNUNET_strdup (server);
- rh->stun_port = port;
- rh->dns_success = GNUNET_NO;
- rh->dns_active = GNUNET_RESOLVER_ip_get (rh->stun_server,
- AF_INET,
- TIMEOUT,
- &stun_dns_callback, rh);
- if (NULL == rh->dns_active)
- {
- GNUNET_NAT_stun_make_request_cancel (rh);
- return NULL;
- }
- return rh;
-}
-
-/* end of nat_stun.c */
diff --git a/src/peerinfo-tool/Makefile.am b/src/peerinfo-tool/Makefile.am
index f22380a9e..c79c3ac68 100644
--- a/src/peerinfo-tool/Makefile.am
+++ b/src/peerinfo-tool/Makefile.am
@@ -19,7 +19,6 @@ gnunet_peerinfo_SOURCES = \
gnunet_peerinfo_LDADD = \
$(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \
- $(top_builddir)/src/nat/libgnunetnat.la \
$(top_builddir)/src/transport/libgnunettransport.la \
$(top_builddir)/src/hello/libgnunethello.la \
$(top_builddir)/src/statistics/libgnunetstatistics.la \
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am
index 8f2df40a1..0b523eecc 100644
--- a/src/transport/Makefile.am
+++ b/src/transport/Makefile.am
@@ -235,7 +235,6 @@ gnunet_transport_profiler_SOURCES = \
gnunet-transport-profiler.c
gnunet_transport_profiler_LDADD = \
libgnunettransport.la \
- $(top_builddir)/src/nat/libgnunetnat.la \
$(top_builddir)/src/hello/libgnunethello.la \
$(top_builddir)/src/ats/libgnunetats.la \
$(top_builddir)/src/util/libgnunetutil.la \
@@ -267,7 +266,6 @@ gnunet_service_transport_LDADD = \
$(top_builddir)/src/ats/libgnunetats.la \
$(top_builddir)/src/hello/libgnunethello.la \
$(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \
- $(top_builddir)/src/nat/libgnunetnat.la \
$(top_builddir)/src/statistics/libgnunetstatistics.la \
$(top_builddir)/src/util/libgnunetutil.la \
$(GN_GLPK) \
@@ -371,7 +369,6 @@ libgnunet_plugin_transport_http_client_la_LIBADD = \
$(top_builddir)/src/statistics/libgnunetstatistics.la \
$(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \
$(LIB_GNURL) \
- $(top_builddir)/src/nat/libgnunetnat.la \
$(top_builddir)/src/util/libgnunetutil.la
libgnunet_plugin_transport_http_client_la_LDFLAGS = \
$(GN_PLUGIN_LDFLAGS)
@@ -402,7 +399,6 @@ libgnunet_plugin_transport_https_client_la_LIBADD = \
$(top_builddir)/src/statistics/libgnunetstatistics.la \
$(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \
$(LIB_GNURL) \
- $(top_builddir)/src/nat/libgnunetnat.la \
$(top_builddir)/src/util/libgnunetutil.la
libgnunet_plugin_transport_https_client_la_LDFLAGS = \
$(GN_PLUGIN_LDFLAGS)
@@ -418,7 +414,7 @@ libgnunet_plugin_transport_https_server_la_LIBADD = \
$(top_builddir)/src/hello/libgnunethello.la \
$(top_builddir)/src/statistics/libgnunetstatistics.la \
$(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \
- $(top_builddir)/src/nat/libgnunetnat.la \
+ $(top_builddir)/src/nat/libgnunetnatnew.la \
$(top_builddir)/src/util/libgnunetutil.la
libgnunet_plugin_transport_https_server_la_LDFLAGS = \
$(GN_LIBMHD) \
@@ -1175,7 +1171,6 @@ test_quota_compliance_wlan_asymmetric_LDADD = \
test_quota_compliance_bluetooth_SOURCES = \
test_quota_compliance.c
test_quota_compliance_bluetooth_LDADD = \
- $(top_builddir)/src/nat/libgnunetnat.la \
libgnunettransport.la \
$(top_builddir)/src/hello/libgnunethello.la \
$(top_builddir)/src/ats/libgnunetats.la \