add template for NAT service
authorChristian Grothoff <christian@grothoff.org>
Mon, 31 Oct 2016 10:30:38 +0000 (10:30 +0000)
committerChristian Grothoff <christian@grothoff.org>
Mon, 31 Oct 2016 10:30:38 +0000 (10:30 +0000)
src/nat/Makefile.am
src/nat/gnunet-service-nat.c [new file with mode: 0644]

index e4b01391671248b5bba7c68f84b23da90dbf796c..d8d50e1a42e7f65a74ad66f1f46044c91a17bf8a 100644 (file)
@@ -38,7 +38,9 @@ bin_PROGRAMS = \
  gnunet-nat
 
 libexec_PROGRAMS = \
- $(NATBIN) 
+ $(NATBIN) \
+ gnunet-service-nat
+
 
 gnunet_nat_server_SOURCES = \
  gnunet-nat-server.c nat.h
@@ -54,7 +56,7 @@ gnunet_helper_nat_client_SOURCES = \
 
 
 gnunet_nat_SOURCES = \
-gnunet-nat.c nat.h
+  gnunet-nat.c nat.h
 gnunet_nat_LDADD = \
   libgnunetnat.la \
   $(top_builddir)/src/util/libgnunetutil.la
@@ -90,6 +92,15 @@ libgnunetnatnew_la_LDFLAGS = \
   $(GN_LIB_LDFLAGS) $(WINFLAGS) \
   -version-info 2:0:0
 
+gnunet_service_nat_SOURCES = \
+ gnunet-service-nat.c
+gnunet_service_nat_LDADD = \
+  $(top_builddir)/src/util/libgnunetutil.la \
+  $(top_builddir)/src/statistics/libgnunetstatistics.la \
+  $(LIBGCRYPT_LIBS) \
+  -lgcrypt \
+  $(GN_LIBINTL)
+
 check_PROGRAMS = \
   test_nat \
   test_nat_mini \
@@ -113,7 +124,6 @@ test_nat_mini_LDADD = \
  libgnunetnat.la \
  $(top_builddir)/src/util/libgnunetutil.la 
 
-
 test_nat_test_SOURCES = \
   test_nat_test.c
 test_nat_test_LDADD = \
diff --git a/src/nat/gnunet-service-nat.c b/src/nat/gnunet-service-nat.c
new file mode 100644 (file)
index 0000000..6077970
--- /dev/null
@@ -0,0 +1,277 @@
+/*
+  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 */