# for our hostname (to get our own IP), in ms
DYNDNS_FREQUENCY = 140000
+[gnunet-nat-server]
+HOSTNAME = nat.gnunet.org
+PORT = 5724
[transport-tcp]
# Use 0 to ONLY advertise as a peer behind NAT (no port binding)
-version-info 0:0:0
check_PROGRAMS = \
- test-nat
+ test_nat \
+ test_nat_test
if ENABLE_TEST_RUN
TESTS = $(check_PROGRAMS)
test_nat_SOURCES = \
test_nat.c
-
test_nat_LDADD = \
$(top_builddir)/src/nat/libgnunetnat.la \
- $(top_builddir)/src/util/libgnunetutil.la \
- @LIBCURL@
+ $(top_builddir)/src/util/libgnunetutil.la
+
+
+test_nat_test_SOURCES = \
+ test_nat_test.c
+test_nat_test_LDADD = \
+ $(top_builddir)/src/nat/libgnunetnat.la \
+ $(top_builddir)/src/util/libgnunetutil.la
+
EXTRA_DIST = \
- test_nat_data.conf
+ test_nat_data.conf \
+ test_nat_test_data.conf
\ No newline at end of file
*/
static const struct GNUNET_CONFIGURATION_Handle *cfg;
+
/**
* Try contacting the peer using autonomous
* NAT traveral method.
struct GNUNET_NAT_Handle *h;
struct sockaddr_in sa;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Asking for connection reversal with %x and code %u\n",
+ (unsigned int) dst_ipv4,
+ (unsigned int) dport);
h = GNUNET_NAT_register (cfg,
is_tcp,
dport,
0, NULL, NULL,
NULL, NULL, NULL);
memset (&sa, 0, sizeof (sa));
+ sa.sin_family = AF_INET;
#if HAVE_SOCKADDR_IN_SIN_LEN
sa.sin_len = sizeof (sa);
#endif
ctx->s)) )
{
if (-1 == GNUNET_NETWORK_socket_send (ctx->s, &ctx->data, sizeof (ctx->data)))
- GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "send");
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, "send");
GNUNET_NETWORK_socket_shutdown (ctx->s, SHUT_RDWR);
}
GNUNET_NETWORK_socket_close (ctx->s);
struct sockaddr_in sa;
struct TcpContext *ctx;
- s = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0);
+ s = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0);
if (NULL == s)
{
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "socket");
return;
}
memset (&sa, 0, sizeof (sa));
+ sa.sin_family = AF_INET;
#if HAVE_SOCKADDR_IN_SIN_LEN
sa.sin_len = sizeof (sa);
#endif
sa.sin_addr.s_addr = dst_ipv4;
sa.sin_port = htons (dport);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending TCP message to `%s'\n",
+ GNUNET_a2s ((struct sockaddr*) &sa, sizeof (sa)));
if ( (GNUNET_OK !=
GNUNET_NETWORK_socket_connect (s,
(const struct sockaddr*) &sa, sizeof (sa))) &&
struct GNUNET_NETWORK_Handle *s;
struct sockaddr_in sa;
- s = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_DGRAM, 0);
+ s = GNUNET_NETWORK_socket_create (AF_INET, SOCK_DGRAM, 0);
if (NULL == s)
{
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "socket");
return;
}
memset (&sa, 0, sizeof (sa));
+ sa.sin_family = AF_INET;
#if HAVE_SOCKADDR_IN_SIN_LEN
sa.sin_len = sizeof (sa);
#endif
sa.sin_addr.s_addr = dst_ipv4;
sa.sin_port = htons (dport);
- if (-1 == GNUNET_NETWORK_socket_sendto (s, &data, sizeof(data), (const struct sockaddr*) &sa, sizeof (sa)))
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending UDP packet to `%s'\n",
+ GNUNET_a2s ((struct sockaddr*) &sa, sizeof (sa)));
+ if (-1 == GNUNET_NETWORK_socket_sendto (s,
+ &data, sizeof(data),
+ (const struct sockaddr*) &sa, sizeof (sa)))
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "sendto");
GNUNET_NETWORK_socket_close (s);
}
const struct GNUNET_NAT_TestMessage *tm;
uint16_t dport;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received test request\n");
tm = (const struct GNUNET_NAT_TestMessage*) msg;
dport = ntohs (tm->dport);
if (0 == dport)
if ( (args[0] == NULL) ||
(1 != SSCANF (args[0], "%u", &port)) ||
(0 == port) ||
- (65536 >= port) )
+ (65536 <= port) )
{
fprintf (stderr,
- _("Please pass valid port number as the first argument!\n"));
+ _("Please pass valid port number as the first argument! (got `%s')\n"),
+ args[0]);
return;
}
memset (&in4, 0, sizeof (in4));
memset (&in6, 0, sizeof (in6));
+ in4.sin_family = AF_INET;
in4.sin_port = htons ((uint16_t) port);
+ in6.sin6_family = AF_INET6;
in6.sin6_port = htons ((uint16_t) port);
#if HAVE_SOCKADDR_IN_SIN_LEN
in4.sin_len = sizeof (in);
#define DYNDNS_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 7)
/**
- * How long until we give up on transmitting the welcome message?
+ * How long until we give up trying to resolve our own hostname?
*/
-#define HOSTNAME_RESOLVE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
+#define HOSTNAME_RESOLVE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1)
/**
};
+/**
+ * Entry we keep for each connection to the gnunet-nat-service.
+ */
+struct ClientActivity
+{
+ /**
+ * This is a doubly-linked list.
+ */
+ struct ClientActivity *next;
+
+ /**
+ * This is a doubly-linked list.
+ */
+ struct ClientActivity *prev;
+
+ /**
+ * Socket of the incoming connection.
+ */
+ struct GNUNET_CLIENT_Connection *client;
+
+};
+
+
/**
* Handle to a NAT test.
*/
/**
* Head of list of nat activities.
*/
- struct NatActivity *head;
+ struct NatActivity *na_head;
/**
* Tail of list of nat activities.
*/
- struct NatActivity *tail;
+ struct NatActivity *na_tail;
+
+ /**
+ * Head of list of client activities.
+ */
+ struct ClientActivity *ca_head;
+
+ /**
+ * Tail of list of client activities.
+ */
+ struct ClientActivity *ca_tail;
/**
* Identity of task for the listen socket (if any)
na->rtask = GNUNET_SCHEDULER_NO_TASK;
tst = na->h;
- GNUNET_CONTAINER_DLL_remove (tst->head,
- tst->tail,
+ GNUNET_CONTAINER_DLL_remove (tst->na_head,
+ tst->na_tail,
na);
if ( (NULL != tc->write_ready) &&
(GNUNET_NETWORK_fdset_isset (tc->read_ready,
wl->sock,
&do_read,
wl);
- GNUNET_CONTAINER_DLL_insert (tst->head,
- tst->tail,
+ GNUNET_CONTAINER_DLL_insert (tst->na_head,
+ tst->na_tail,
wl);
}
socklen_t addrlen)
{
struct GNUNET_NAT_Test *h = cls;
+ struct ClientActivity *ca;
struct GNUNET_CLIENT_Connection *client;
struct GNUNET_NAT_TestMessage msg;
const struct sockaddr_in *sa;
return;
if (addrlen != sizeof (struct sockaddr_in))
return; /* ignore IPv6 here */
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Asking gnunet-nat-server to connect to `%s'\n",
+ GNUNET_a2s (addr, addrlen));
sa = (const struct sockaddr_in*) addr;
msg.header.size = htons (sizeof(struct GNUNET_NAT_TestMessage));
msg.header.type = htons (GNUNET_MESSAGE_TYPE_NAT_TEST);
client = GNUNET_CLIENT_connect ("gnunet-nat-server",
h->cfg);
+ if (NULL == client)
+ return;
+ ca = GNUNET_malloc (sizeof (struct ClientActivity));
+ ca->client = client;
+ GNUNET_CONTAINER_DLL_insert (h->ca_head,
+ h->ca_tail,
+ ca);
GNUNET_break (GNUNET_OK ==
GNUNET_CLIENT_transmit_and_get_response (client,
&msg.header,
GNUNET_TIME_UNIT_SECONDS,
GNUNET_YES,
NULL, NULL));
- GNUNET_CLIENT_disconnect (client, GNUNET_YES);
}
GNUNET_NAT_test_stop (struct GNUNET_NAT_Test *tst)
{
struct NatActivity *pos;
+ struct ClientActivity *cpos;
- while (NULL != (pos = tst->head))
+ while (NULL != (cpos = tst->ca_head))
+ {
+ GNUNET_CONTAINER_DLL_remove (tst->ca_head,
+ tst->ca_tail,
+ cpos);
+ GNUNET_CLIENT_disconnect (cpos->client, GNUNET_NO);
+ GNUNET_free (cpos);
+ }
+ while (NULL != (pos = tst->na_head))
{
- GNUNET_CONTAINER_DLL_remove (tst->head,
- tst->tail,
+ GNUNET_CONTAINER_DLL_remove (tst->na_head,
+ tst->na_tail,
pos);
GNUNET_SCHEDULER_cancel (pos->rtask);
GNUNET_NETWORK_socket_close (pos->sock);
--- /dev/null
+/*
+ This file is part of GNUnet.
+ (C) 2009, 2011 Christian Grothoff (and other contributing authors)
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * Testcase for the NAT testing code.
+ *
+ * @file nat/test_nat_test.c
+ * @brief Testcase for NAT testing functions
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "gnunet_common.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_nat_lib.h"
+
+
+#define VERBOSE GNUNET_YES
+
+
+/**
+ * Time to wait before stopping NAT test, in seconds
+ */
+#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15)
+
+
+static int ret = 1;
+
+static struct GNUNET_NAT_Test *tst;
+
+static GNUNET_SCHEDULER_TaskIdentifier end;
+
+static void
+end_test (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ GNUNET_NAT_test_stop (tst);
+}
+
+static void
+report_success (void *cls,
+ int success)
+{
+ GNUNET_assert (GNUNET_OK == success);
+ ret = 0;
+ GNUNET_SCHEDULER_cancel (end);
+ end = GNUNET_SCHEDULER_add_now (&end_test, NULL);
+}
+
+/**
+ * Main function run with scheduler.
+ */
+static void
+run (void *cls,
+ char *const *args,
+ const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ tst = GNUNET_NAT_test_start (cfg, GNUNET_YES,
+ 1285, 1285,
+ &report_success, NULL);
+ if (NULL == tst)
+ return;
+ end = GNUNET_SCHEDULER_add_delayed (TIMEOUT,
+ &end_test,
+ NULL);
+}
+
+
+int
+main (int argc, char *const argv[])
+{
+ struct GNUNET_GETOPT_CommandLineOption options[] = {
+ GNUNET_GETOPT_OPTION_END
+ };
+ struct GNUNET_OS_Process *gns;
+ char *const argv_prog[] = {
+ "test-nat-test",
+ "-c",
+ "test_nat_test_data.conf",
+ "-L",
+#if VERBOSE
+ "DEBUG",
+#else
+ "WARNING",
+#endif
+ NULL
+ };
+
+ GNUNET_log_setup ("test-nat-test",
+#if VERBOSE
+ "DEBUG",
+#else
+ "WARNING",
+#endif
+ NULL);
+ gns = GNUNET_OS_start_process (NULL, NULL,
+ "gnunet-nat-server",
+ "gnunet-nat-server",
+#if VERBOSE
+ "-L",
+ "DEBUG",
+#endif
+ "12345",
+ NULL);
+ GNUNET_assert (NULL != gns);
+ GNUNET_PROGRAM_run (5, argv_prog,
+ "test-nat-test", "nohelp",
+ options,
+ &run, NULL);
+ GNUNET_break (0 == GNUNET_OS_process_kill (gns, SIGTERM));
+ GNUNET_break (GNUNET_OK ==
+ GNUNET_OS_process_wait (gns));
+ GNUNET_OS_process_close (gns);
+ return ret;
+}
+
+/* end of test_nat_test.c */
--- /dev/null
+[PATHS]
+SERVICEHOME = /tmp/nat-test
+# SERVICEHOME = /var/lib/gnunet/
+# DEFAULTCONFIG = /etc/gnunet.conf
+# If 'DEFAULTCONFIG' is not defined, the current
+# configuration file is assumed to be the default,
+# which is what we want by default...
+
+[gnunet-nat-server]
+HOSTNAME = localhost
+PORT = 12345
+
+[nat]
+# Are we behind NAT?
+BEHIND_NAT = YES
+
+# Is the NAT hole-punched?
+PUNCHED_NAT = NO
+
+# Disable UPNP by default until it gets cleaner!
+ENABLE_UPNP = YES
+
+# Use addresses from the local network interfaces (inluding loopback, but also others)
+USE_LOCALADDR = YES
+
+# External IP address of the NAT box (if known); IPv4 dotted-decimal ONLY at this time (should allow DynDNS!)
+# normal interface IP address for non-NATed peers;
+# possibly auto-detected (using UPnP) if possible if not specified
+# EXTERNAL_ADDRESS =
+
+# Should we use ICMP-based NAT traversal to try connect to NATed peers
+# or, if we are behind NAT, to allow connections to us?
+ENABLE_ICMP_CLIENT = YES
+ENABLE_ICMP_SERVER = YES
+
+# IP address of the interface connected to the NAT box; IPv4 dotted-decimal ONLY;
+# normal interface IP address for non-NATed peers;
+# likely auto-detected (via interface list) if not specified (!)
+INTERNAL_ADDRESS = 127.0.0.1
+
+# Disable IPv6 support
+DISABLEV6 = YES
+x
if (remaining.rel_value == 0)
{
/* signal timeout! */
- conn->receiver_handler (conn->receiver_handler_cls, NULL);
+ if (NULL != conn->receiver_handler)
+ conn->receiver_handler (conn->receiver_handler_cls, NULL);
return;
}
/* back to receive -- either for more data or to call callback! */
{
/* already disconnected, fail instantly! */
GNUNET_break (0); /* this should not happen in well-written code! */
- handler (handler_cls, NULL);
+ if (NULL != handler)
+ handler (handler_cls, NULL);
return;
}
sock->receiver_handler = handler;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
_("Could not submit request, not expecting to receive a response.\n"));
#endif
- tc->rn (tc->rn_cls, NULL);
+ if (NULL != tc->rn)
+ tc->rn (tc->rn_cls, NULL);
GNUNET_free (tc);
return 0;
}
ret = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle));
ret->fd = accept (desc->fd, address, address_len);
- ret->af = address->sa_family;
+ if (address != NULL)
+ ret->af = address->sa_family;
+ else
+ ret->af = desc->af;
if (ret->fd == INVALID_SOCKET)
{
#ifdef MINGW
socket_set_nosigpipe (ret);
#endif
#ifdef AF_UNIX
- if (address->sa_family != AF_UNIX)
+ if (ret->af != AF_UNIX)
#endif
socket_set_nodelay (ret);
return ret;
};
struct GNUNET_GETOPT_CommandLineOption *allopts;
const char *gargs;
+ char *lpfx;
+ char *spc;
logfile = NULL;
gargs = getenv ("GNUNET_ARGS");
&cmd_sorter);
loglev = GNUNET_strdup ("WARNING");
cc.cfgfile = GNUNET_strdup (GNUNET_DEFAULT_USER_CONFIG_FILE);
+ lpfx = GNUNET_strdup (binaryName);
+ if (NULL != (spc = strstr (lpfx, " ")))
+ *spc = '\0';
if ((-1 == (ret = GNUNET_GETOPT_run (binaryName,
allopts,
(unsigned int) argc, argv))) ||
((GNUNET_OK !=
- GNUNET_log_setup (binaryName,
+ GNUNET_log_setup (lpfx,
loglev,
logfile)) ||
(GNUNET_OK != GNUNET_CONFIGURATION_load (cfg, cc.cfgfile))))
GNUNET_free_non_null (cc.cfgfile);
GNUNET_free (loglev);
GNUNET_free (allopts);
+ GNUNET_free (lpfx);
return GNUNET_SYSERR;
}
GNUNET_free (allopts);
+ GNUNET_free (lpfx);
/* run */
cc.args = &argv[ret];