--- /dev/null
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2016 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/gnunet-service-nat.c
+ * @brief network address translation traversal service
+ * @author Christian Grothoff
+ *
+ * The purpose of this service is to enable transports to
+ * traverse NAT routers, by providing traversal options and
+ * knowledge about the local network topology.
+ */
+#include "platform.h"
+#include <math.h>
+#include "gnunet_util_lib.h"
+#include "gnunet_protocols.h"
+#include "gnunet_signatures.h"
+#include "gnunet_statistics_service.h"
+#include "gnunet_nat_service.h"
+#include "nat.h"
+#include <gcrypt.h>
+
+
+/**
+ * Internal data structure we track for each of our clients.
+ */
+struct ClientHandle
+{
+
+ /**
+ * Kept in a DLL.
+ */
+ struct ClientHandle *next;
+
+ /**
+ * Kept in a DLL.
+ */
+ struct ClientHandle *prev;
+
+ /**
+ * Underlying handle for this client with the service.
+ */
+ struct GNUNET_SERVICE_Client *client;
+
+ /**
+ * Message queue for communicating with the client.
+ */
+ struct GNUNET_MQ_Handle *mq;
+
+ /**
+ * What does this client care about?
+ */
+ enum GNUNET_NAT_RegisterFlags flags;
+
+ /**
+ * Client's IPPROTO, e.g. IPPROTO_UDP or IPPROTO_TCP.
+ */
+ uint8_t proto;
+
+ /**
+ * Port we would like as we are configured to use this one for
+ * advertising (in addition to the one we are binding to).
+ */
+ uint16_t adv_port;
+
+ /**
+ * Number of addresses that this service is bound to.
+ */
+ uint16_t num_addrs;
+
+ /**
+ * Array of addresses used by the service.
+ */
+ struct sockaddr **addrs;
+
+};
+
+
+/**
+ * Handle to our current configuration.
+ */
+static const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+/**
+ * Handle to the statistics service.
+ */
+static struct GNUNET_STATISTICS_Handle *stats;
+
+/**
+ * Task scheduled to periodically scan our network interfaces.
+ */
+static struct GNUNET_SCHEDULER_Task *scan_task;
+
+/**
+ * Head of client DLL.
+ */
+static struct ClientHandle *ch_head;
+
+/**
+ * Tail of client DLL.
+ */
+static struct ClientHandle *ch_tail;
+
+
+/**
+ * Handler for #GNUNET_MESSAGE_TYPE_NAT_REGISTER message from client.
+ * We remember the client for updates upon future NAT events.
+ *
+ * @param cls client who sent the message
+ * @param message the message received
+ */
+static int
+check_register (void *cls,
+ const struct GNUNET_NAT_RegisterMessage *message)
+{
+ GNUNET_break (0); // not implemented
+ return GNUNET_SYSERR;
+}
+
+
+/**
+ * Handler for #GNUNET_MESSAGE_TYPE_NAT_REGISTER message from client.
+ * We remember the client for updates upon future NAT events.
+ *
+ * @param cls client who sent the message
+ * @param message the message received
+ */
+static void
+handle_register (void *cls,
+ const struct GNUNET_NAT_RegisterMessage *message)
+{
+ struct ClientHandle *ch = cls;
+ // struct GNUNET_MQ_Handle *mq;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received REGISTER message from client\n");
+ GNUNET_SERVICE_client_continue (ch->client);
+}
+
+
+/**
+ * Task run during shutdown.
+ *
+ * @param cls unused
+ */
+static void
+shutdown_task (void *cls)
+{
+ if (NULL != scan_task)
+ {
+ GNUNET_SCHEDULER_cancel (scan_task);
+ scan_task = NULL;
+ }
+ if (NULL != stats)
+ {
+ GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
+ stats = NULL;
+ }
+}
+
+
+/**
+ * Handle network size estimate clients.
+ *
+ * @param cls closure
+ * @param c configuration to use
+ * @param service the initialized service
+ */
+static void
+run (void *cls,
+ const struct GNUNET_CONFIGURATION_Handle *c,
+ struct GNUNET_SERVICE_Handle *service)
+{
+ cfg = c;
+ GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
+ NULL);
+ stats = GNUNET_STATISTICS_create ("nat",
+ cfg);
+}
+
+
+/**
+ * Callback called when a client connects to the service.
+ *
+ * @param cls closure for the service
+ * @param c the new client that connected to the service
+ * @param mq the message queue used to send messages to the client
+ * @return a `struct ClientHandle`
+ */
+static void *
+client_connect_cb (void *cls,
+ struct GNUNET_SERVICE_Client *c,
+ struct GNUNET_MQ_Handle *mq)
+{
+ struct ClientHandle *ch;
+
+ ch = GNUNET_new (struct ClientHandle);
+ ch->mq = mq;
+ ch->client = c;
+ GNUNET_CONTAINER_DLL_insert (ch_head,
+ ch_tail,
+ ch);
+ return ch;
+}
+
+
+/**
+ * Callback called when a client disconnected from the service
+ *
+ * @param cls closure for the service
+ * @param c the client that disconnected
+ * @param internal_cls a `struct ClientHandle *`
+ */
+static void
+client_disconnect_cb (void *cls,
+ struct GNUNET_SERVICE_Client *c,
+ void *internal_cls)
+{
+ struct ClientHandle *ch = internal_cls;
+
+ GNUNET_CONTAINER_DLL_remove (ch_head,
+ ch_tail,
+ ch);
+ GNUNET_free (ch);
+}
+
+
+/**
+ * Define "main" method using service macro.
+ */
+GNUNET_SERVICE_MAIN
+("nat",
+ GNUNET_SERVICE_OPTION_NONE,
+ &run,
+ &client_connect_cb,
+ &client_disconnect_cb,
+ NULL,
+ GNUNET_MQ_hd_var_size (register,
+ GNUNET_MESSAGE_TYPE_NAT_REGISTER,
+ struct GNUNET_NAT_RegisterMessage,
+ NULL),
+ GNUNET_MQ_handler_end ());
+
+
+#if defined(LINUX) && defined(__GLIBC__)
+#include <malloc.h>
+
+/**
+ * MINIMIZE heap size (way below 128k) since this process doesn't need much.
+ */
+void __attribute__ ((constructor))
+GNUNET_ARM_memory_init ()
+{
+ mallopt (M_TRIM_THRESHOLD, 4 * 1024);
+ mallopt (M_TOP_PAD, 1 * 1024);
+ malloc_trim (0);
+}
+#endif
+
+/* end of gnunet-service-nat.c */