From 331e0e66df283db2d305bd6b80ac2b1896271d4f Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Mon, 31 Oct 2016 10:30:38 +0000 Subject: [PATCH] add template for NAT service --- src/nat/Makefile.am | 16 +- src/nat/gnunet-service-nat.c | 277 +++++++++++++++++++++++++++++++++++ 2 files changed, 290 insertions(+), 3 deletions(-) create mode 100644 src/nat/gnunet-service-nat.c diff --git a/src/nat/Makefile.am b/src/nat/Makefile.am index e4b013916..d8d50e1a4 100644 --- a/src/nat/Makefile.am +++ b/src/nat/Makefile.am @@ -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 index 000000000..607797081 --- /dev/null +++ b/src/nat/gnunet-service-nat.c @@ -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 +#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 + + +/** + * 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 + +/** + * 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 */ -- 2.25.1