gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r11514 - gnunet/src/arm


From: gnunet
Subject: [GNUnet-SVN] r11514 - gnunet/src/arm
Date: Tue, 25 May 2010 18:44:26 +0200

Author: grothoff
Date: 2010-05-25 18:44:26 +0200 (Tue, 25 May 2010)
New Revision: 11514

Added:
   gnunet/src/arm/gnunet-service-arm.h
   gnunet/src/arm/gnunet-service-arm_interceptor.c
Removed:
   gnunet/src/arm/gnunet-service-manager.c
   gnunet/src/arm/gnunet_service_arm_.h
Modified:
   gnunet/src/arm/Makefile.am
   gnunet/src/arm/gnunet-service-arm.c
Log:
renaming files to fit conventions

Modified: gnunet/src/arm/Makefile.am
===================================================================
--- gnunet/src/arm/Makefile.am  2010-05-25 16:42:39 UTC (rev 11513)
+++ gnunet/src/arm/Makefile.am  2010-05-25 16:44:26 UTC (rev 11514)
@@ -34,8 +34,8 @@
   $(GN_LIBINTL)
 
 gnunet_service_arm_SOURCES = \
- gnunet-service-arm.c  gnunet_service_arm_.h \
- gnunet-service-manager.c       
+ gnunet-service-arm.c  gnunet-service-arm.h \
+ gnunet-service-arm_interceptor.c       
 gnunet_service_arm_LDADD = \
   $(top_builddir)/src/util/libgnunetutil.la \
   $(GN_LIBINTL)

Modified: gnunet/src/arm/gnunet-service-arm.c
===================================================================
--- gnunet/src/arm/gnunet-service-arm.c 2010-05-25 16:42:39 UTC (rev 11513)
+++ gnunet/src/arm/gnunet-service-arm.c 2010-05-25 16:44:26 UTC (rev 11514)
@@ -37,7 +37,7 @@
 #include "gnunet_protocols.h"
 #include "gnunet_service_lib.h"
 #include "gnunet_signal_lib.h"
-#include "gnunet_service_arm_.h"
+#include "gnunet-service-arm.h"
 #include "arm.h"
 
 

Copied: gnunet/src/arm/gnunet-service-arm.h (from rev 11512, 
gnunet/src/arm/gnunet_service_arm_.h)
===================================================================
--- gnunet/src/arm/gnunet-service-arm.h                         (rev 0)
+++ gnunet/src/arm/gnunet-service-arm.h 2010-05-25 16:44:26 UTC (rev 11514)
@@ -0,0 +1,46 @@
+/*
+     This file is part of GNUnet.
+     (C) 2010 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 2, 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.
+*/
+
+/**
+ * @file arm/gnunet_service_arm_.h
+ * @brief function prototypes for gnunet_service_arm.c, and 
gnunet_service_manager.c
+ * @author Safey Abdel Halim
+ */
+
+#ifndef GNUNET_SERVICE_ARM__H
+#define GNUNET_SERVICE_ARM__H
+
+void start_service (struct GNUNET_SERVER_Client *client,
+                   const char *servicename);
+
+/**
+ * Stop listening for connections to a service.
+ * 
+ * @param serviceName name of service to stop listening for
+ * @return GNUNET_OK if we stopped to listen, GNUNET_NO if we were
+ *         not listening
+ */
+int stop_listening (const char *serviceName);
+
+void prepareServices (const struct GNUNET_CONFIGURATION_Handle
+                     *configurationHandle,
+                     struct GNUNET_SCHEDULER_Handle *sched);
+
+#endif

Copied: gnunet/src/arm/gnunet-service-arm_interceptor.c (from rev 11513, 
gnunet/src/arm/gnunet-service-manager.c)
===================================================================
--- gnunet/src/arm/gnunet-service-arm_interceptor.c                             
(rev 0)
+++ gnunet/src/arm/gnunet-service-arm_interceptor.c     2010-05-25 16:44:26 UTC 
(rev 11514)
@@ -0,0 +1,1066 @@
+/*
+     This file is part of GNUnet.
+     (C) 2009, 2010 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 2, 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.
+*/
+/**
+ * @file arm/gnunet-service-arm_interceptor.c
+ * @brief listen to incoming connections from clients to services,
+ * start services for which incoming an incoming connection occur,
+ * and relay communication between the client and the service for 
+ * that first incoming connection.
+ *
+ * @author Safey Abdel Halim
+ * @author Christian Grothoff
+ */
+
+#include "platform.h"
+#include "gnunet_service_lib.h"
+#include "gnunet_configuration_lib.h"
+#include "gnunet_constants.h"
+#include "gnunet_client_lib.h"
+#include "gnunet_container_lib.h"
+#include "gnunet-service-arm.h"
+
+
+#define DEBUG_SERVICE_MANAGER GNUNET_NO
+
+#define BUFFER_SIZE (64 * 1024)
+
+/**
+ * Problem forwarding from client to service.
+ */
+#define REASON_CLIENT_TO_SERVICE 1
+
+/**
+ * Problem forwarding from service to client.
+ */
+#define REASON_SERVICE_TO_CLIENT 2
+
+/**
+ * Problem in both directions.
+ */
+#define REASON_ERROR 3
+
+
+/**
+ *
+ */
+struct ServiceListeningInfo
+{
+  /**
+   * This is a linked list.
+   */
+  struct ServiceListeningInfo *next;
+
+  /**
+   * This is a linked list.
+   */
+  struct ServiceListeningInfo *prev;
+
+  /**
+   * Name of the service being forwarded.
+   */
+  char *serviceName;
+
+  /**
+   *
+   */
+  struct sockaddr *service_addr;
+
+  /**
+   *
+   */
+  socklen_t service_addr_len;
+
+  /**
+   * Our listening socket.
+   */
+  struct GNUNET_NETWORK_Handle *listeningSocket;
+
+  /**
+   * Task doing the accepting.
+   */
+  GNUNET_SCHEDULER_TaskIdentifier acceptTask;
+};
+
+/**
+ * Information of the connection: client-arm-service
+ */
+struct ForwardedConnection
+{
+  /**
+   *
+   */
+  struct GNUNET_NETWORK_Handle *armClientSocket;
+
+  /**
+   *
+   */
+  struct GNUNET_NETWORK_Handle *armServiceSocket;
+
+  /**
+   *
+   */
+  struct ServiceListeningInfo *listen_info;
+
+  /**
+   *
+   */
+  char service_to_client_buffer[BUFFER_SIZE];
+
+  /**
+   *
+   */
+  char client_to_service_buffer[BUFFER_SIZE];
+
+  /**
+   *
+   */
+  char client_addr[32];
+
+  /**
+   *
+   */
+  const char *client_to_service_bufferPos;
+
+  /**
+   *
+   */
+  const char *service_to_client_bufferPos;
+
+  /**
+   * Timeout for forwarding.
+   */
+  struct GNUNET_TIME_Absolute timeout;
+  
+  /**
+   * Current back-off value.
+   */
+  struct GNUNET_TIME_Relative back_off;
+  
+  /**
+   * Task that tries to initiate forwarding.
+   */
+  GNUNET_SCHEDULER_TaskIdentifier start_task;
+
+  /**
+   *
+   */
+  GNUNET_SCHEDULER_TaskIdentifier client_to_service_task;
+
+  /**
+   *
+   */
+  GNUNET_SCHEDULER_TaskIdentifier service_to_client_task;
+
+  /**
+   *
+   */
+  ssize_t client_to_service_bufferDataLength;
+
+  /**
+   *
+   */
+  ssize_t service_to_client_bufferDataLength;
+
+  /**
+   *
+   */
+  socklen_t client_addr_len;
+
+  /**
+   * Have we ever successfully written data to the service?
+   */
+  int first_write_done;
+};
+
+
+/**
+ * Array with the names of the services started by default.
+ */
+static char **defaultServicesList;
+
+/**
+ * Size of the defaultServicesList array.
+ */
+static unsigned int numDefaultServices;
+
+/**
+ *
+ */
+static const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+/**
+ *
+ */
+static struct GNUNET_SCHEDULER_Handle *scheduler;
+
+/**
+ *
+ */
+static struct ServiceListeningInfo *serviceListeningInfoList_head;
+
+/**
+ *
+ */
+static struct ServiceListeningInfo *serviceListeningInfoList_tail;
+
+
+/**
+ * Put the default services represented by a space separated string into an 
array of strings
+ * 
+ * @param services space separated string of default services
+ */
+static void
+addDefaultServicesToList (const char *services)
+{
+  unsigned int i;
+  const char *token;
+  char *s;
+
+  if (strlen (services) == 0)
+    return;
+  s = GNUNET_strdup (services);
+  token = strtok (s, " ");
+  while (NULL != token)
+    {
+      numDefaultServices++;
+      token = strtok (NULL, " ");
+    }
+  GNUNET_free (s);
+
+  defaultServicesList = GNUNET_malloc (numDefaultServices * sizeof (char *));
+  i = 0;
+  s = GNUNET_strdup (services);
+  token = strtok (s, " ");
+  while (NULL != token)
+    {
+      defaultServicesList[i++] = GNUNET_strdup (token);
+      token = strtok (NULL, " ");
+    }
+  GNUNET_free (s);
+  GNUNET_assert (i == numDefaultServices);
+}
+
+/**
+ * Checks whether the serviceName is in the list of default services
+ * 
+ * @param serviceName string to check its existance in the list
+ * @return GNUNET_YES if the service is started by default
+ */
+static int
+isInDefaultList (const char *serviceName)
+{
+  unsigned int i;
+  for (i = 0; i < numDefaultServices; i++)
+    if (strcmp (serviceName, defaultServicesList[i]) == 0)
+      return GNUNET_YES;    
+  return GNUNET_NO;
+}
+
+
+/**
+ * Close forwarded connection (partial or full).
+ *
+ * @param fc connection to close 
+ * @param reason which direction to close
+ */
+static void
+closeClientAndServiceSockets (struct ForwardedConnection *fc, 
+                             int reason)
+{
+  if (0 != (REASON_SERVICE_TO_CLIENT & reason)) 
+    {      
+#if DEBUG_SERVICE_MANAGER
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                 "Stopping forwarding from service to client\n",
+                 fc->listen_info->serviceName);
+#endif
+      if (fc->service_to_client_task != GNUNET_SCHEDULER_NO_TASK)
+       {
+         GNUNET_SCHEDULER_cancel (scheduler, fc->service_to_client_task);    
+         fc->service_to_client_task = GNUNET_SCHEDULER_NO_TASK;
+       }
+      if (fc->armClientSocket != NULL)
+       GNUNET_NETWORK_socket_shutdown (fc->armClientSocket,
+                                       SHUT_WR);
+      if (fc->armServiceSocket != NULL)
+       GNUNET_NETWORK_socket_shutdown (fc->armServiceSocket,
+                                       SHUT_RD);
+    }
+  if (0 != (REASON_CLIENT_TO_SERVICE & reason)) 
+    {
+#if DEBUG_SERVICE_MANAGER
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                 "Stopping forwarding from client to service\n",
+                 fc->listen_info->serviceName);
+#endif
+      if (fc->client_to_service_task != GNUNET_SCHEDULER_NO_TASK) 
+       {
+         GNUNET_SCHEDULER_cancel (scheduler,
+                                  fc->client_to_service_task);
+         fc->client_to_service_task = GNUNET_SCHEDULER_NO_TASK;
+       }
+      if (fc->armClientSocket != NULL)
+       GNUNET_NETWORK_socket_shutdown (fc->armClientSocket,
+                                       SHUT_RD);
+      if (fc->armServiceSocket != NULL)
+       GNUNET_NETWORK_socket_shutdown (fc->armServiceSocket,
+                                       SHUT_WR);
+    }
+  if ( (fc->client_to_service_task != GNUNET_SCHEDULER_NO_TASK) ||
+       (fc->service_to_client_task != GNUNET_SCHEDULER_NO_TASK) )
+    return;
+#if DEBUG_SERVICE_MANAGER
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "Closing forwarding connection (done with both directions)\n");
+#endif
+  if (fc->start_task != GNUNET_SCHEDULER_NO_TASK)
+    GNUNET_SCHEDULER_cancel (scheduler,
+                            fc->start_task);
+  if ( (NULL != fc->armClientSocket) &&
+       (GNUNET_SYSERR ==
+       GNUNET_NETWORK_socket_close (fc->armClientSocket)) )
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "close");
+  if ( (NULL != fc->armServiceSocket) &&
+       (GNUNET_SYSERR ==
+       GNUNET_NETWORK_socket_close (fc->armServiceSocket)) )
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "close");
+  GNUNET_free (fc->listen_info->serviceName);             
+  GNUNET_free (fc->listen_info->service_addr);
+  GNUNET_free (fc->listen_info);       
+  GNUNET_free (fc);
+}
+
+
+/**
+ *
+ */
+static void
+receiveFromClient (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
+
+
+/**
+ *
+ */
+static void
+receiveFromService (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
+
+
+/**
+ *
+ */
+static void
+start_forwarding (void *cls,
+                 const struct GNUNET_SCHEDULER_TaskContext *tc);
+
+
+
+/**
+ * Forward messages sent from service to client
+ * 
+ * @param cls callback data, struct ForwardedConnection for the communication 
between client and service
+ * @param tc context
+ */
+static void
+forwardToClient (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct ForwardedConnection *fc = cls;
+  ssize_t numberOfBytesSent;
+
+  fc->service_to_client_task = GNUNET_SCHEDULER_NO_TASK;
+  if (GNUNET_YES != GNUNET_NETWORK_fdset_isset (tc->write_ready,
+                                               fc->armClientSocket))
+    {
+      fc->service_to_client_task = 
+       GNUNET_SCHEDULER_add_write_net (scheduler,
+                                       GNUNET_TIME_UNIT_FOREVER_REL,
+                                       fc->armClientSocket,
+                                       &forwardToClient, fc);
+      return;
+    }
+  /* Forwarding service response to client */
+  numberOfBytesSent =
+    GNUNET_NETWORK_socket_send (fc->armClientSocket,
+                               fc->service_to_client_bufferPos,
+                               fc->service_to_client_bufferDataLength);
+  if (numberOfBytesSent <= 0)
+    {
+      if ( (errno != EPIPE) &&
+          (errno != ECONNRESET) )
+       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                   "Failed to forward %u bytes of data to client: %s\n",
+                   fc->service_to_client_bufferDataLength,
+                   STRERROR (errno));
+      closeClientAndServiceSockets (fc,
+                                   REASON_SERVICE_TO_CLIENT);
+      return;
+    }
+#if DEBUG_SERVICE_MANAGER
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "Forwarded %d bytes to client\n",
+             numberOfBytesSent);
+#endif
+  if (numberOfBytesSent < fc->service_to_client_bufferDataLength)
+    {
+      fc->service_to_client_bufferPos += numberOfBytesSent;
+      fc->service_to_client_bufferDataLength -= numberOfBytesSent;
+      fc->service_to_client_task = 
+       GNUNET_SCHEDULER_add_write_net (scheduler, 
+                                       GNUNET_TIME_UNIT_FOREVER_REL,
+                                       fc->armClientSocket,
+                                       &forwardToClient, 
+                                       fc);
+      return;
+    }
+  fc->service_to_client_task =
+    GNUNET_SCHEDULER_add_read_net (scheduler, 
+                                  GNUNET_TIME_UNIT_FOREVER_REL,
+                                  fc->armServiceSocket,
+                                  &receiveFromService, 
+                                  fc);
+}
+
+
+/**
+ * Receive service messages sent by the service and forward it to client
+ * 
+ * @param cls callback data, struct ForwardedConnection for the communication 
between client and service
+ * @param tc scheduler context
+ */
+static void
+receiveFromService (void *cls, 
+                   const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct ForwardedConnection *fc = cls;
+  struct GNUNET_TIME_Relative rem;
+
+  fc->service_to_client_task = GNUNET_SCHEDULER_NO_TASK;
+  if ( (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) &&
+       (fc->first_write_done != GNUNET_YES) )
+    {
+      closeClientAndServiceSockets (fc, REASON_ERROR);
+      return;
+    }
+  if (GNUNET_YES != GNUNET_NETWORK_fdset_isset (tc->read_ready,
+                                               fc->armServiceSocket))
+    {
+      fc->service_to_client_task =
+       GNUNET_SCHEDULER_add_read_net (scheduler,
+                                      GNUNET_TIME_UNIT_FOREVER_REL,
+                                      fc->armServiceSocket,
+                                      &receiveFromService, fc);
+      return;
+    }
+  fc->service_to_client_bufferPos = fc->service_to_client_buffer;
+  fc->service_to_client_bufferDataLength =
+    GNUNET_NETWORK_socket_recv (fc->armServiceSocket,
+                               fc->service_to_client_buffer, 
+                               BUFFER_SIZE);
+  if (fc->service_to_client_bufferDataLength <= 0)
+    {
+      if (fc->service_to_client_bufferDataLength == 0)
+       {
+#if DEBUG_SERVICE_MANAGER
+         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                     "Service `%s' stopped sending data.\n",
+                     fc->listen_info->serviceName);
+#endif
+       }
+      if (fc->first_write_done != GNUNET_YES)
+       {
+         fc->service_to_client_bufferDataLength = 0;
+         GNUNET_break (GNUNET_OK ==
+                       GNUNET_NETWORK_socket_close (fc->armServiceSocket));
+         fc->armServiceSocket = NULL;
+         if ( (fc->client_to_service_bufferDataLength > 0) &&
+              (fc->client_to_service_task != GNUNET_SCHEDULER_NO_TASK) )
+           {
+             GNUNET_SCHEDULER_cancel (scheduler,
+                                      fc->client_to_service_task);
+             fc->service_to_client_task = GNUNET_SCHEDULER_NO_TASK;
+           }
+         fc->back_off = GNUNET_TIME_relative_multiply (fc->back_off, 2);
+#if DEBUG_SERVICE_MANAGER
+         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                     "Failed to connected to service `%s' at `%s', will try 
again in %llu ms\n",
+                     fc->listen_info->serviceName,
+                     GNUNET_a2s (fc->listen_info->service_addr,
+                                 fc->listen_info->service_addr_len),
+                     (unsigned long long) GNUNET_TIME_relative_min 
(fc->back_off,
+                                                                    
rem).value);
+#endif
+         rem = GNUNET_TIME_absolute_get_remaining (fc->timeout);
+         GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == fc->start_task);
+         fc->start_task
+           = GNUNET_SCHEDULER_add_delayed (scheduler,
+                                           GNUNET_TIME_relative_min 
(fc->back_off,
+                                                                     rem),
+                                           &start_forwarding,
+                                           fc);
+       }
+      else
+       {
+#if DEBUG_SERVICE_MANAGER
+         if (fc->service_to_client_bufferDataLength != 0)
+           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                       "Error receiving from service: %s\n", 
+                       STRERROR (errno));
+#endif
+         closeClientAndServiceSockets (fc, REASON_SERVICE_TO_CLIENT);
+       }
+      return;
+    }
+  fc->first_write_done = GNUNET_YES;
+#if DEBUG_SERVICE_MANAGER
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "Received %d bytes for client\n",
+             fc->service_to_client_bufferDataLength);
+#endif
+  fc->service_to_client_task = 
+    GNUNET_SCHEDULER_add_write_net (scheduler, 
+                                   GNUNET_TIME_UNIT_FOREVER_REL,
+                                   fc->armClientSocket,
+                                   &forwardToClient, fc);
+}
+
+
+/**
+ * Forward client message to service
+ * 
+ * @param cls callback data, struct ForwardedConnection for the communication 
between client and service
+ * @param tc scheduler context
+ */
+static void
+forwardToService (void *cls, 
+                 const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct ForwardedConnection *fc = cls;
+  ssize_t numberOfBytesSent;
+  struct GNUNET_TIME_Relative rem;
+
+  fc->client_to_service_task = GNUNET_SCHEDULER_NO_TASK;
+  if ( (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) &&
+       (fc->first_write_done != GNUNET_YES) )
+    {
+      closeClientAndServiceSockets (fc, REASON_ERROR);
+      return;
+    }
+  if (GNUNET_YES != GNUNET_NETWORK_fdset_isset (tc->write_ready,
+                                               fc->armServiceSocket))
+    {
+      fc->client_to_service_task = 
+       GNUNET_SCHEDULER_add_write_net (scheduler,
+                                       GNUNET_TIME_UNIT_FOREVER_REL,
+                                       fc->armServiceSocket,
+                                       &forwardToService, fc);
+      return;
+    }
+  numberOfBytesSent =
+    GNUNET_NETWORK_socket_send (fc->armServiceSocket,
+                               fc->client_to_service_bufferPos,
+                               fc->client_to_service_bufferDataLength);
+  if (numberOfBytesSent <= 0)
+    {
+      if (GNUNET_YES != fc->first_write_done)
+       {
+         GNUNET_break (GNUNET_OK ==
+                       GNUNET_NETWORK_socket_close (fc->armServiceSocket));
+         fc->armServiceSocket = NULL;
+         if ( (fc->service_to_client_bufferDataLength == 0) &&
+              (fc->service_to_client_task != GNUNET_SCHEDULER_NO_TASK) )
+           {
+             GNUNET_SCHEDULER_cancel (scheduler,
+                                      fc->service_to_client_task);
+             fc->service_to_client_task = GNUNET_SCHEDULER_NO_TASK;
+           }
+         fc->back_off = GNUNET_TIME_relative_multiply (fc->back_off, 2);
+#if DEBUG_SERVICE_MANAGER
+         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                     "Failed to connect to service `%s' at `%s', will try 
again in %llu ms\n",
+                     fc->listen_info->serviceName,
+                     GNUNET_a2s (fc->listen_info->service_addr,
+                                 fc->listen_info->service_addr_len),
+                     (unsigned long long) GNUNET_TIME_relative_min 
(fc->back_off,
+                                                                    
rem).value);
+#endif
+         rem = GNUNET_TIME_absolute_get_remaining (fc->timeout);
+         GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == fc->start_task);
+         fc->start_task 
+           = GNUNET_SCHEDULER_add_delayed (scheduler,
+                                           GNUNET_TIME_relative_min 
(fc->back_off,
+                                                                     rem),
+                                           &start_forwarding,
+                                           fc);
+       }
+      else
+       {
+         if ( (errno != EPIPE) &&
+              (errno != ECONNRESET) )
+           GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                       "Failed to forward data to service: %s\n",
+                       STRERROR (errno));
+         closeClientAndServiceSockets (fc,
+                                       REASON_CLIENT_TO_SERVICE);
+       }
+      return;
+    }
+#if DEBUG_SERVICE_MANAGER
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "Forwarded %d bytes to service\n",
+             numberOfBytesSent);
+#endif
+  fc->first_write_done = GNUNET_YES;
+  if (numberOfBytesSent < fc->client_to_service_bufferDataLength)
+    {
+      fc->client_to_service_bufferPos += numberOfBytesSent;
+      fc->client_to_service_bufferDataLength -= numberOfBytesSent;
+      fc->client_to_service_task = 
+       GNUNET_SCHEDULER_add_write_net (scheduler, 
+                                       GNUNET_TIME_UNIT_FOREVER_REL,
+                                       fc->armServiceSocket,
+                                       &forwardToService, fc);
+      return;
+    }
+  fc->client_to_service_task =
+    GNUNET_SCHEDULER_add_read_net (scheduler, 
+                                  GNUNET_TIME_UNIT_FOREVER_REL,
+                                  fc->armClientSocket,
+                                  &receiveFromClient, fc);
+}
+
+
+/**
+ * Read data from the client and then forward it to the service.
+ * 
+ * @param cls callback data,   struct ForwardedConnection for the 
communication between client and service
+ * @param tc context 
+ */
+static void
+receiveFromClient (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct ForwardedConnection *fc = cls;
+
+  fc->client_to_service_task = GNUNET_SCHEDULER_NO_TASK;
+  if (GNUNET_YES != GNUNET_NETWORK_fdset_isset (tc->read_ready,
+                                               fc->armClientSocket))
+    {
+      fc->client_to_service_task =
+       GNUNET_SCHEDULER_add_read_net (scheduler,
+                                      GNUNET_TIME_UNIT_FOREVER_REL,
+                                      fc->armClientSocket,
+                                      &receiveFromClient, fc);
+      return;
+    }
+  fc->client_to_service_bufferPos = fc->client_to_service_buffer;
+  fc->client_to_service_bufferDataLength =
+    GNUNET_NETWORK_socket_recv (fc->armClientSocket,
+                               fc->client_to_service_buffer, 
+                               BUFFER_SIZE);
+  if (fc->client_to_service_bufferDataLength <= 0)
+    {
+      if (fc->client_to_service_bufferDataLength == 0)
+       {
+#if DEBUG_SERVICE_MANAGER
+         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                     "Client closed connection with service `%s'\n",
+                     fc->listen_info->serviceName);
+#endif
+       }
+      else
+       {
+#if DEBUG_SERVICE_MANAGER
+         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                     "Error receiving from client: %s\n",
+                     STRERROR (errno));
+#endif
+       }
+      closeClientAndServiceSockets (fc, REASON_CLIENT_TO_SERVICE);
+      return;
+    }
+#if DEBUG_SERVICE_MANAGER
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "Received %d bytes for service\n",
+             fc->client_to_service_bufferDataLength);
+#endif
+  if (fc->armServiceSocket != NULL)        
+    fc->client_to_service_task = 
+      GNUNET_SCHEDULER_add_write_net (scheduler,
+                                     GNUNET_TIME_UNIT_FOREVER_REL,
+                                     fc->armServiceSocket,
+                                     &forwardToService, fc);
+}
+
+
+/**
+ *
+ */
+static void
+start_forwarding (void *cls,
+                 const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct ForwardedConnection *fc = cls;
+  struct GNUNET_TIME_Relative rem;
+
+  fc->start_task = GNUNET_SCHEDULER_NO_TASK;
+  if ( (NULL != tc) &&
+       (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) )
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                 _("Unable to forward to service `%s': shutdown\n"),
+                 fc->listen_info->serviceName);
+      closeClientAndServiceSockets (fc, REASON_ERROR);
+      return;
+    }
+  rem = GNUNET_TIME_absolute_get_remaining (fc->timeout);
+  if (rem.value == 0)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                 _("Unable to forward to service `%s': timeout before 
connect\n"),
+                 fc->listen_info->serviceName);
+      closeClientAndServiceSockets (fc, REASON_ERROR);
+      return;
+    }
+  fc->armServiceSocket =
+    GNUNET_NETWORK_socket_create (fc->listen_info->service_addr->sa_family,
+                                 SOCK_STREAM, 0);
+  if (NULL == fc->armServiceSocket)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                 _ ("Unable to start service `%s': %s\n"),
+                 fc->listen_info->serviceName,
+                 STRERROR (errno));
+      closeClientAndServiceSockets (fc, REASON_ERROR);
+      return;
+    }
+  if ( (GNUNET_SYSERR ==
+       GNUNET_NETWORK_socket_connect (fc->armServiceSocket,
+                                      fc->listen_info->service_addr,
+                                      fc->listen_info->service_addr_len)) &&
+       (errno != EINPROGRESS) )
+    {
+      GNUNET_break (GNUNET_OK ==
+                   GNUNET_NETWORK_socket_close (fc->armServiceSocket));
+      fc->armServiceSocket = NULL;
+      fc->back_off = GNUNET_TIME_relative_multiply (fc->back_off, 2);
+  #if DEBUG_SERVICE_MANAGER
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                 "Failed to connected to service `%s' at `%s', will try again 
in %llu ms\n",
+                 fc->listen_info->serviceName,
+                 GNUNET_a2s (fc->listen_info->service_addr,
+                             fc->listen_info->service_addr_len),
+                 (unsigned long long) GNUNET_TIME_relative_min (fc->back_off,
+                                                                rem).value);
+#endif
+      GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == fc->start_task);
+      fc->start_task
+       = GNUNET_SCHEDULER_add_delayed (scheduler,
+                                       GNUNET_TIME_relative_min (fc->back_off,
+                                                                 rem),
+                                       &start_forwarding,
+                                       fc);
+      return;
+    }
+#if DEBUG_SERVICE_MANAGER
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "Connected to service, now starting forwarding\n");
+#endif
+  if (fc->client_to_service_task == GNUNET_SCHEDULER_NO_TASK)
+    {
+      if (fc->client_to_service_bufferDataLength == 0) 
+       fc->client_to_service_task =
+         GNUNET_SCHEDULER_add_read_net (scheduler,
+                                        GNUNET_TIME_UNIT_FOREVER_REL,
+                                        fc->armClientSocket,
+                                        &receiveFromClient, fc);
+      else
+       fc->client_to_service_task = 
+         GNUNET_SCHEDULER_add_write_net (scheduler, 
+                                         GNUNET_TIME_UNIT_FOREVER_REL,
+                                         fc->armServiceSocket,
+                                         &forwardToService, fc);
+    }
+  if (fc->service_to_client_task == GNUNET_SCHEDULER_NO_TASK)
+    {
+      if (fc->service_to_client_bufferDataLength == 0) 
+       fc->service_to_client_task =
+         GNUNET_SCHEDULER_add_read_net (scheduler,
+                                        GNUNET_TIME_UNIT_FOREVER_REL,
+                                        fc->armServiceSocket,
+                                        &receiveFromService, fc);
+      else
+       fc->service_to_client_task = 
+         GNUNET_SCHEDULER_add_write_net (scheduler, 
+                                         GNUNET_TIME_UNIT_FOREVER_REL,
+                                         fc->armClientSocket,
+                                         &forwardToClient, fc);
+    }
+}
+
+
+
+/**
+ *
+ */
+int
+stop_listening (const char *serviceName)
+{
+  struct ServiceListeningInfo *pos;
+  struct ServiceListeningInfo *next;
+  int ret;
+  
+  ret = GNUNET_NO;
+  next = serviceListeningInfoList_head;
+  while (NULL != (pos = next))
+    {
+      next = pos->next;
+      if ( (serviceName != NULL) &&
+          (strcmp (pos->serviceName, serviceName) != 0) )
+       continue;
+      if (pos->acceptTask != GNUNET_SCHEDULER_NO_TASK)
+       GNUNET_SCHEDULER_cancel (scheduler, pos->acceptTask);
+      GNUNET_break (GNUNET_OK ==
+                   GNUNET_NETWORK_socket_close (pos->listeningSocket));
+      GNUNET_CONTAINER_DLL_remove (serviceListeningInfoList_head,
+                                  serviceListeningInfoList_tail, 
+                                  pos);
+      GNUNET_free (pos->serviceName);             
+      GNUNET_free (pos->service_addr);
+      GNUNET_free (pos); 
+      ret = GNUNET_OK;
+    }
+  return ret;
+}
+
+
+/**
+ * First connection has come to the listening socket associated with the 
service,
+ * create the service in order to relay the incoming connection to it
+ * 
+ * @param cls callback data, struct ServiceListeningInfo describing a listen 
socket
+ * @param tc context 
+ */
+static void
+acceptConnection (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct ServiceListeningInfo *serviceListeningInfo = cls;
+  struct ForwardedConnection *fc;
+
+  serviceListeningInfo->acceptTask = GNUNET_SCHEDULER_NO_TASK;
+  if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
+    return;
+  fc = GNUNET_malloc (sizeof (struct ForwardedConnection));
+  fc->listen_info = serviceListeningInfo;
+  fc->service_to_client_bufferPos = fc->service_to_client_buffer;
+  fc->client_to_service_bufferPos = fc->client_to_service_buffer;
+  fc->client_addr_len = sizeof (fc->client_addr);
+  fc->armClientSocket = GNUNET_NETWORK_socket_accept 
(serviceListeningInfo->listeningSocket,
+                                                     (struct sockaddr*) 
fc->client_addr,
+                                                     &fc->client_addr_len);
+  if (NULL == fc->armClientSocket)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                 _("Unable to accept connection for service `%s': %s\n"),
+                 serviceListeningInfo->serviceName,
+                 STRERROR (errno));
+      GNUNET_free (fc);
+      serviceListeningInfo->acceptTask =
+       GNUNET_SCHEDULER_add_read_net (scheduler,
+                                      GNUNET_TIME_UNIT_FOREVER_REL, 
+                                      serviceListeningInfo->listeningSocket,
+                                      &acceptConnection,
+                                      serviceListeningInfo);
+      return;
+    }
+  GNUNET_break (GNUNET_OK ==
+               GNUNET_NETWORK_socket_close 
(serviceListeningInfo->listeningSocket));
+  GNUNET_CONTAINER_DLL_remove (serviceListeningInfoList_head,
+                              serviceListeningInfoList_tail, 
+                              serviceListeningInfo);
+  start_service (NULL, serviceListeningInfo->serviceName);
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO, 
+             _("Service `%s' started\n"),
+             fc->listen_info->serviceName);
+  fc->timeout = GNUNET_TIME_relative_to_absolute 
(GNUNET_CONSTANTS_SERVICE_TIMEOUT);
+  fc->back_off = GNUNET_TIME_UNIT_MILLISECONDS;
+  fc->client_to_service_task =
+    GNUNET_SCHEDULER_add_read_net (scheduler,
+                                  GNUNET_TIME_UNIT_FOREVER_REL,
+                                  fc->armClientSocket,
+                                  &receiveFromClient, fc);
+  GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == fc->start_task);
+  fc->start_task 
+    = GNUNET_SCHEDULER_add_now (scheduler,
+                               &start_forwarding,
+                               fc);
+}
+
+
+/**
+ * Creating a listening socket for each of the service's addresses and
+ * wait for the first incoming connection to it
+ * 
+ * @param sa address associated with the service
+ * @param addr_len length of sa
+ * @param serviceName the name of the service in question
+ */
+static void
+createListeningSocket (struct sockaddr *sa, 
+                      socklen_t addr_len,
+                      const char *serviceName)
+{
+  const static int on = 1;
+  struct GNUNET_NETWORK_Handle *sock;
+  struct ServiceListeningInfo *serviceListeningInfo;
+
+  switch (sa->sa_family)
+    {
+    case AF_INET:
+      sock = GNUNET_NETWORK_socket_create (PF_INET, SOCK_STREAM, 0);
+      break;
+    case AF_INET6:
+      sock = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0);
+      break;
+    default:
+      sock = NULL;
+      break;
+    }
+  if (NULL == sock)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                 _("Unable to create socket for service `%s'"),
+                 serviceName);
+      GNUNET_free (sa);
+      return;
+    }
+  if (GNUNET_NETWORK_socket_setsockopt
+      (sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) != GNUNET_OK)
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                         "setsockopt");
+#ifdef IPV6_V6ONLY
+  if ( (sa->sa_family == AF_INET6) &&
+       (GNUNET_NETWORK_socket_setsockopt
+       (sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on)) != GNUNET_OK))
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                        "setsockopt");
+#endif
+
+  if (GNUNET_NETWORK_socket_bind
+      (sock, (const struct sockaddr *) sa, addr_len) != GNUNET_OK)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                 _("Unable to bind listening socket for service `%s' to 
address `%s': %s\n"),
+                 serviceName,
+                 GNUNET_a2s (sa, addr_len),
+                 STRERROR (errno));
+      GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
+      GNUNET_free (sa);
+      return;
+    }
+  if (GNUNET_NETWORK_socket_listen (sock, 5) != GNUNET_OK)
+    {
+      GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
+                          "listen");
+      GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
+      GNUNET_free (sa);
+      return;
+    }
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+             _("ARM now monitors connections to service `%s' at `%s'\n"),
+             serviceName,
+             GNUNET_a2s (sa, addr_len));
+  serviceListeningInfo = GNUNET_malloc (sizeof (struct ServiceListeningInfo));
+  serviceListeningInfo->serviceName = GNUNET_strdup (serviceName);
+  serviceListeningInfo->service_addr = sa;
+  serviceListeningInfo->service_addr_len = addr_len;
+  serviceListeningInfo->listeningSocket = sock;
+  serviceListeningInfo->acceptTask =
+    GNUNET_SCHEDULER_add_read_net (scheduler,
+                                  GNUNET_TIME_UNIT_FOREVER_REL, sock,
+                                  &acceptConnection,
+                                  serviceListeningInfo);
+  GNUNET_CONTAINER_DLL_insert (serviceListeningInfoList_head,
+                              serviceListeningInfoList_tail,
+                              serviceListeningInfo);
+}
+
+
+/**
+ * Callback function, checks whether the current tokens are representing a 
service,
+ * gets its addresses and create listening socket for it.
+ * 
+ * @param cls callback data, not used
+ * @param section configuration section
+ * @param option configuration option
+ * @param value the option's value
+ */
+static void
+checkPortNumberCB (void *cls,
+                  const char *section, 
+                  const char *option, 
+                  const char *value)
+{
+  struct sockaddr **addrs;
+  socklen_t *addr_lens;
+  int ret;
+  unsigned int i;
+  
+  if ( (strcasecmp (section, "arm") == 0) ||
+       (strcasecmp (option, "AUTOSTART") != 0) ||
+       (strcasecmp (value, "YES") != 0) ||
+       (isInDefaultList (section) == GNUNET_YES) )
+    return;
+  if (0 >= (ret = GNUNET_SERVICE_get_server_addresses (section, cfg, &addrs,
+                                                      &addr_lens)))
+    return;
+  /* this will free (or capture) addrs[i] */
+  for (i = 0; i < ret; i++)
+    createListeningSocket (addrs[i], addr_lens[i], section);
+  GNUNET_free (addrs);
+  GNUNET_free (addr_lens);
+}
+
+
+/**
+ * Entry point to the Service Manager
+ *
+ * @param configurationHandle configuration to use to get services
+ * @param sched scheduler to handle clients and services communications
+ */
+void
+prepareServices (const struct GNUNET_CONFIGURATION_Handle
+                *configurationHandle, struct GNUNET_SCHEDULER_Handle *sched)
+{
+  char *defaultServicesString;
+
+  scheduler = sched;
+  cfg = configurationHandle;
+  /* Split the default services into a list */
+  if (GNUNET_OK ==
+      GNUNET_CONFIGURATION_get_value_string (cfg, "arm", "DEFAULTSERVICES",
+                                            &defaultServicesString))
+    {
+      addDefaultServicesToList (defaultServicesString);
+      GNUNET_free (defaultServicesString);    
+    }
+  /* Spot the services from the configuration and create a listening
+     socket for each */
+  GNUNET_CONFIGURATION_iterate (cfg, &checkPortNumberCB, NULL);
+}
+
+/* end of gnunet-service-arm_interceptor.c */

Deleted: gnunet/src/arm/gnunet-service-manager.c
===================================================================
--- gnunet/src/arm/gnunet-service-manager.c     2010-05-25 16:42:39 UTC (rev 
11513)
+++ gnunet/src/arm/gnunet-service-manager.c     2010-05-25 16:44:26 UTC (rev 
11514)
@@ -1,1066 +0,0 @@
-/*
-     This file is part of GNUnet.
-     (C) 2009, 2010 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 2, 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.
-*/
-/**
- * @file arm/gnunet-service-manager.c
- * @brief listen to incoming connections from clients to services,
- * start services for which incoming an incoming connection occur,
- * and relay communication between the client and the service for 
- * that first incoming connection.
- *
- * @author Safey Abdel Halim
- * @author Christian Grothoff
- */
-
-#include "platform.h"
-#include "gnunet_service_lib.h"
-#include "gnunet_configuration_lib.h"
-#include "gnunet_constants.h"
-#include "gnunet_client_lib.h"
-#include "gnunet_container_lib.h"
-#include "gnunet_service_arm_.h"
-
-
-#define DEBUG_SERVICE_MANAGER GNUNET_NO
-
-#define BUFFER_SIZE (64 * 1024)
-
-/**
- * Problem forwarding from client to service.
- */
-#define REASON_CLIENT_TO_SERVICE 1
-
-/**
- * Problem forwarding from service to client.
- */
-#define REASON_SERVICE_TO_CLIENT 2
-
-/**
- * Problem in both directions.
- */
-#define REASON_ERROR 3
-
-
-/**
- *
- */
-struct ServiceListeningInfo
-{
-  /**
-   * This is a linked list.
-   */
-  struct ServiceListeningInfo *next;
-
-  /**
-   * This is a linked list.
-   */
-  struct ServiceListeningInfo *prev;
-
-  /**
-   * Name of the service being forwarded.
-   */
-  char *serviceName;
-
-  /**
-   *
-   */
-  struct sockaddr *service_addr;
-
-  /**
-   *
-   */
-  socklen_t service_addr_len;
-
-  /**
-   * Our listening socket.
-   */
-  struct GNUNET_NETWORK_Handle *listeningSocket;
-
-  /**
-   * Task doing the accepting.
-   */
-  GNUNET_SCHEDULER_TaskIdentifier acceptTask;
-};
-
-/**
- * Information of the connection: client-arm-service
- */
-struct ForwardedConnection
-{
-  /**
-   *
-   */
-  struct GNUNET_NETWORK_Handle *armClientSocket;
-
-  /**
-   *
-   */
-  struct GNUNET_NETWORK_Handle *armServiceSocket;
-
-  /**
-   *
-   */
-  struct ServiceListeningInfo *listen_info;
-
-  /**
-   *
-   */
-  char service_to_client_buffer[BUFFER_SIZE];
-
-  /**
-   *
-   */
-  char client_to_service_buffer[BUFFER_SIZE];
-
-  /**
-   *
-   */
-  char client_addr[32];
-
-  /**
-   *
-   */
-  const char *client_to_service_bufferPos;
-
-  /**
-   *
-   */
-  const char *service_to_client_bufferPos;
-
-  /**
-   * Timeout for forwarding.
-   */
-  struct GNUNET_TIME_Absolute timeout;
-  
-  /**
-   * Current back-off value.
-   */
-  struct GNUNET_TIME_Relative back_off;
-  
-  /**
-   * Task that tries to initiate forwarding.
-   */
-  GNUNET_SCHEDULER_TaskIdentifier start_task;
-
-  /**
-   *
-   */
-  GNUNET_SCHEDULER_TaskIdentifier client_to_service_task;
-
-  /**
-   *
-   */
-  GNUNET_SCHEDULER_TaskIdentifier service_to_client_task;
-
-  /**
-   *
-   */
-  ssize_t client_to_service_bufferDataLength;
-
-  /**
-   *
-   */
-  ssize_t service_to_client_bufferDataLength;
-
-  /**
-   *
-   */
-  socklen_t client_addr_len;
-
-  /**
-   * Have we ever successfully written data to the service?
-   */
-  int first_write_done;
-};
-
-
-/**
- * Array with the names of the services started by default.
- */
-static char **defaultServicesList;
-
-/**
- * Size of the defaultServicesList array.
- */
-static unsigned int numDefaultServices;
-
-/**
- *
- */
-static const struct GNUNET_CONFIGURATION_Handle *cfg;
-
-/**
- *
- */
-static struct GNUNET_SCHEDULER_Handle *scheduler;
-
-/**
- *
- */
-static struct ServiceListeningInfo *serviceListeningInfoList_head;
-
-/**
- *
- */
-static struct ServiceListeningInfo *serviceListeningInfoList_tail;
-
-
-/**
- * Put the default services represented by a space separated string into an 
array of strings
- * 
- * @param services space separated string of default services
- */
-static void
-addDefaultServicesToList (const char *services)
-{
-  unsigned int i;
-  const char *token;
-  char *s;
-
-  if (strlen (services) == 0)
-    return;
-  s = GNUNET_strdup (services);
-  token = strtok (s, " ");
-  while (NULL != token)
-    {
-      numDefaultServices++;
-      token = strtok (NULL, " ");
-    }
-  GNUNET_free (s);
-
-  defaultServicesList = GNUNET_malloc (numDefaultServices * sizeof (char *));
-  i = 0;
-  s = GNUNET_strdup (services);
-  token = strtok (s, " ");
-  while (NULL != token)
-    {
-      defaultServicesList[i++] = GNUNET_strdup (token);
-      token = strtok (NULL, " ");
-    }
-  GNUNET_free (s);
-  GNUNET_assert (i == numDefaultServices);
-}
-
-/**
- * Checks whether the serviceName is in the list of default services
- * 
- * @param serviceName string to check its existance in the list
- * @return GNUNET_YES if the service is started by default
- */
-static int
-isInDefaultList (const char *serviceName)
-{
-  unsigned int i;
-  for (i = 0; i < numDefaultServices; i++)
-    if (strcmp (serviceName, defaultServicesList[i]) == 0)
-      return GNUNET_YES;    
-  return GNUNET_NO;
-}
-
-
-/**
- * Close forwarded connection (partial or full).
- *
- * @param fc connection to close 
- * @param reason which direction to close
- */
-static void
-closeClientAndServiceSockets (struct ForwardedConnection *fc, 
-                             int reason)
-{
-  if (0 != (REASON_SERVICE_TO_CLIENT & reason)) 
-    {      
-#if DEBUG_SERVICE_MANAGER
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                 "Stopping forwarding from service to client\n",
-                 fc->listen_info->serviceName);
-#endif
-      if (fc->service_to_client_task != GNUNET_SCHEDULER_NO_TASK)
-       {
-         GNUNET_SCHEDULER_cancel (scheduler, fc->service_to_client_task);    
-         fc->service_to_client_task = GNUNET_SCHEDULER_NO_TASK;
-       }
-      if (fc->armClientSocket != NULL)
-       GNUNET_NETWORK_socket_shutdown (fc->armClientSocket,
-                                       SHUT_WR);
-      if (fc->armServiceSocket != NULL)
-       GNUNET_NETWORK_socket_shutdown (fc->armServiceSocket,
-                                       SHUT_RD);
-    }
-  if (0 != (REASON_CLIENT_TO_SERVICE & reason)) 
-    {
-#if DEBUG_SERVICE_MANAGER
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                 "Stopping forwarding from client to service\n",
-                 fc->listen_info->serviceName);
-#endif
-      if (fc->client_to_service_task != GNUNET_SCHEDULER_NO_TASK) 
-       {
-         GNUNET_SCHEDULER_cancel (scheduler,
-                                  fc->client_to_service_task);
-         fc->client_to_service_task = GNUNET_SCHEDULER_NO_TASK;
-       }
-      if (fc->armClientSocket != NULL)
-       GNUNET_NETWORK_socket_shutdown (fc->armClientSocket,
-                                       SHUT_RD);
-      if (fc->armServiceSocket != NULL)
-       GNUNET_NETWORK_socket_shutdown (fc->armServiceSocket,
-                                       SHUT_WR);
-    }
-  if ( (fc->client_to_service_task != GNUNET_SCHEDULER_NO_TASK) ||
-       (fc->service_to_client_task != GNUNET_SCHEDULER_NO_TASK) )
-    return;
-#if DEBUG_SERVICE_MANAGER
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-             "Closing forwarding connection (done with both directions)\n");
-#endif
-  if (fc->start_task != GNUNET_SCHEDULER_NO_TASK)
-    GNUNET_SCHEDULER_cancel (scheduler,
-                            fc->start_task);
-  if ( (NULL != fc->armClientSocket) &&
-       (GNUNET_SYSERR ==
-       GNUNET_NETWORK_socket_close (fc->armClientSocket)) )
-    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "close");
-  if ( (NULL != fc->armServiceSocket) &&
-       (GNUNET_SYSERR ==
-       GNUNET_NETWORK_socket_close (fc->armServiceSocket)) )
-    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "close");
-  GNUNET_free (fc->listen_info->serviceName);             
-  GNUNET_free (fc->listen_info->service_addr);
-  GNUNET_free (fc->listen_info);       
-  GNUNET_free (fc);
-}
-
-
-/**
- *
- */
-static void
-receiveFromClient (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
-
-
-/**
- *
- */
-static void
-receiveFromService (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
-
-
-/**
- *
- */
-static void
-start_forwarding (void *cls,
-                 const struct GNUNET_SCHEDULER_TaskContext *tc);
-
-
-
-/**
- * Forward messages sent from service to client
- * 
- * @param cls callback data, struct ForwardedConnection for the communication 
between client and service
- * @param tc context
- */
-static void
-forwardToClient (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
-  struct ForwardedConnection *fc = cls;
-  ssize_t numberOfBytesSent;
-
-  fc->service_to_client_task = GNUNET_SCHEDULER_NO_TASK;
-  if (GNUNET_YES != GNUNET_NETWORK_fdset_isset (tc->write_ready,
-                                               fc->armClientSocket))
-    {
-      fc->service_to_client_task = 
-       GNUNET_SCHEDULER_add_write_net (scheduler,
-                                       GNUNET_TIME_UNIT_FOREVER_REL,
-                                       fc->armClientSocket,
-                                       &forwardToClient, fc);
-      return;
-    }
-  /* Forwarding service response to client */
-  numberOfBytesSent =
-    GNUNET_NETWORK_socket_send (fc->armClientSocket,
-                               fc->service_to_client_bufferPos,
-                               fc->service_to_client_bufferDataLength);
-  if (numberOfBytesSent <= 0)
-    {
-      if ( (errno != EPIPE) &&
-          (errno != ECONNRESET) )
-       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                   "Failed to forward %u bytes of data to client: %s\n",
-                   fc->service_to_client_bufferDataLength,
-                   STRERROR (errno));
-      closeClientAndServiceSockets (fc,
-                                   REASON_SERVICE_TO_CLIENT);
-      return;
-    }
-#if DEBUG_SERVICE_MANAGER
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-             "Forwarded %d bytes to client\n",
-             numberOfBytesSent);
-#endif
-  if (numberOfBytesSent < fc->service_to_client_bufferDataLength)
-    {
-      fc->service_to_client_bufferPos += numberOfBytesSent;
-      fc->service_to_client_bufferDataLength -= numberOfBytesSent;
-      fc->service_to_client_task = 
-       GNUNET_SCHEDULER_add_write_net (scheduler, 
-                                       GNUNET_TIME_UNIT_FOREVER_REL,
-                                       fc->armClientSocket,
-                                       &forwardToClient, 
-                                       fc);
-      return;
-    }
-  fc->service_to_client_task =
-    GNUNET_SCHEDULER_add_read_net (scheduler, 
-                                  GNUNET_TIME_UNIT_FOREVER_REL,
-                                  fc->armServiceSocket,
-                                  &receiveFromService, 
-                                  fc);
-}
-
-
-/**
- * Receive service messages sent by the service and forward it to client
- * 
- * @param cls callback data, struct ForwardedConnection for the communication 
between client and service
- * @param tc scheduler context
- */
-static void
-receiveFromService (void *cls, 
-                   const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
-  struct ForwardedConnection *fc = cls;
-  struct GNUNET_TIME_Relative rem;
-
-  fc->service_to_client_task = GNUNET_SCHEDULER_NO_TASK;
-  if ( (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) &&
-       (fc->first_write_done != GNUNET_YES) )
-    {
-      closeClientAndServiceSockets (fc, REASON_ERROR);
-      return;
-    }
-  if (GNUNET_YES != GNUNET_NETWORK_fdset_isset (tc->read_ready,
-                                               fc->armServiceSocket))
-    {
-      fc->service_to_client_task =
-       GNUNET_SCHEDULER_add_read_net (scheduler,
-                                      GNUNET_TIME_UNIT_FOREVER_REL,
-                                      fc->armServiceSocket,
-                                      &receiveFromService, fc);
-      return;
-    }
-  fc->service_to_client_bufferPos = fc->service_to_client_buffer;
-  fc->service_to_client_bufferDataLength =
-    GNUNET_NETWORK_socket_recv (fc->armServiceSocket,
-                               fc->service_to_client_buffer, 
-                               BUFFER_SIZE);
-  if (fc->service_to_client_bufferDataLength <= 0)
-    {
-      if (fc->service_to_client_bufferDataLength == 0)
-       {
-#if DEBUG_SERVICE_MANAGER
-         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                     "Service `%s' stopped sending data.\n",
-                     fc->listen_info->serviceName);
-#endif
-       }
-      if (fc->first_write_done != GNUNET_YES)
-       {
-         fc->service_to_client_bufferDataLength = 0;
-         GNUNET_break (GNUNET_OK ==
-                       GNUNET_NETWORK_socket_close (fc->armServiceSocket));
-         fc->armServiceSocket = NULL;
-         if ( (fc->client_to_service_bufferDataLength > 0) &&
-              (fc->client_to_service_task != GNUNET_SCHEDULER_NO_TASK) )
-           {
-             GNUNET_SCHEDULER_cancel (scheduler,
-                                      fc->client_to_service_task);
-             fc->service_to_client_task = GNUNET_SCHEDULER_NO_TASK;
-           }
-         fc->back_off = GNUNET_TIME_relative_multiply (fc->back_off, 2);
-#if DEBUG_SERVICE_MANAGER
-         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                     "Failed to connected to service `%s' at `%s', will try 
again in %llu ms\n",
-                     fc->listen_info->serviceName,
-                     GNUNET_a2s (fc->listen_info->service_addr,
-                                 fc->listen_info->service_addr_len),
-                     (unsigned long long) GNUNET_TIME_relative_min 
(fc->back_off,
-                                                                    
rem).value);
-#endif
-         rem = GNUNET_TIME_absolute_get_remaining (fc->timeout);
-         GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == fc->start_task);
-         fc->start_task
-           = GNUNET_SCHEDULER_add_delayed (scheduler,
-                                           GNUNET_TIME_relative_min 
(fc->back_off,
-                                                                     rem),
-                                           &start_forwarding,
-                                           fc);
-       }
-      else
-       {
-#if DEBUG_SERVICE_MANAGER
-         if (fc->service_to_client_bufferDataLength != 0)
-           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                       "Error receiving from service: %s\n", 
-                       STRERROR (errno));
-#endif
-         closeClientAndServiceSockets (fc, REASON_SERVICE_TO_CLIENT);
-       }
-      return;
-    }
-  fc->first_write_done = GNUNET_YES;
-#if DEBUG_SERVICE_MANAGER
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-             "Received %d bytes for client\n",
-             fc->service_to_client_bufferDataLength);
-#endif
-  fc->service_to_client_task = 
-    GNUNET_SCHEDULER_add_write_net (scheduler, 
-                                   GNUNET_TIME_UNIT_FOREVER_REL,
-                                   fc->armClientSocket,
-                                   &forwardToClient, fc);
-}
-
-
-/**
- * Forward client message to service
- * 
- * @param cls callback data, struct ForwardedConnection for the communication 
between client and service
- * @param tc scheduler context
- */
-static void
-forwardToService (void *cls, 
-                 const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
-  struct ForwardedConnection *fc = cls;
-  ssize_t numberOfBytesSent;
-  struct GNUNET_TIME_Relative rem;
-
-  fc->client_to_service_task = GNUNET_SCHEDULER_NO_TASK;
-  if ( (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) &&
-       (fc->first_write_done != GNUNET_YES) )
-    {
-      closeClientAndServiceSockets (fc, REASON_ERROR);
-      return;
-    }
-  if (GNUNET_YES != GNUNET_NETWORK_fdset_isset (tc->write_ready,
-                                               fc->armServiceSocket))
-    {
-      fc->client_to_service_task = 
-       GNUNET_SCHEDULER_add_write_net (scheduler,
-                                       GNUNET_TIME_UNIT_FOREVER_REL,
-                                       fc->armServiceSocket,
-                                       &forwardToService, fc);
-      return;
-    }
-  numberOfBytesSent =
-    GNUNET_NETWORK_socket_send (fc->armServiceSocket,
-                               fc->client_to_service_bufferPos,
-                               fc->client_to_service_bufferDataLength);
-  if (numberOfBytesSent <= 0)
-    {
-      if (GNUNET_YES != fc->first_write_done)
-       {
-         GNUNET_break (GNUNET_OK ==
-                       GNUNET_NETWORK_socket_close (fc->armServiceSocket));
-         fc->armServiceSocket = NULL;
-         if ( (fc->service_to_client_bufferDataLength == 0) &&
-              (fc->service_to_client_task != GNUNET_SCHEDULER_NO_TASK) )
-           {
-             GNUNET_SCHEDULER_cancel (scheduler,
-                                      fc->service_to_client_task);
-             fc->service_to_client_task = GNUNET_SCHEDULER_NO_TASK;
-           }
-         fc->back_off = GNUNET_TIME_relative_multiply (fc->back_off, 2);
-#if DEBUG_SERVICE_MANAGER
-         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                     "Failed to connect to service `%s' at `%s', will try 
again in %llu ms\n",
-                     fc->listen_info->serviceName,
-                     GNUNET_a2s (fc->listen_info->service_addr,
-                                 fc->listen_info->service_addr_len),
-                     (unsigned long long) GNUNET_TIME_relative_min 
(fc->back_off,
-                                                                    
rem).value);
-#endif
-         rem = GNUNET_TIME_absolute_get_remaining (fc->timeout);
-         GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == fc->start_task);
-         fc->start_task 
-           = GNUNET_SCHEDULER_add_delayed (scheduler,
-                                           GNUNET_TIME_relative_min 
(fc->back_off,
-                                                                     rem),
-                                           &start_forwarding,
-                                           fc);
-       }
-      else
-       {
-         if ( (errno != EPIPE) &&
-              (errno != ECONNRESET) )
-           GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                       "Failed to forward data to service: %s\n",
-                       STRERROR (errno));
-         closeClientAndServiceSockets (fc,
-                                       REASON_CLIENT_TO_SERVICE);
-       }
-      return;
-    }
-#if DEBUG_SERVICE_MANAGER
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-             "Forwarded %d bytes to service\n",
-             numberOfBytesSent);
-#endif
-  fc->first_write_done = GNUNET_YES;
-  if (numberOfBytesSent < fc->client_to_service_bufferDataLength)
-    {
-      fc->client_to_service_bufferPos += numberOfBytesSent;
-      fc->client_to_service_bufferDataLength -= numberOfBytesSent;
-      fc->client_to_service_task = 
-       GNUNET_SCHEDULER_add_write_net (scheduler, 
-                                       GNUNET_TIME_UNIT_FOREVER_REL,
-                                       fc->armServiceSocket,
-                                       &forwardToService, fc);
-      return;
-    }
-  fc->client_to_service_task =
-    GNUNET_SCHEDULER_add_read_net (scheduler, 
-                                  GNUNET_TIME_UNIT_FOREVER_REL,
-                                  fc->armClientSocket,
-                                  &receiveFromClient, fc);
-}
-
-
-/**
- * Read data from the client and then forward it to the service.
- * 
- * @param cls callback data,   struct ForwardedConnection for the 
communication between client and service
- * @param tc context 
- */
-static void
-receiveFromClient (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
-  struct ForwardedConnection *fc = cls;
-
-  fc->client_to_service_task = GNUNET_SCHEDULER_NO_TASK;
-  if (GNUNET_YES != GNUNET_NETWORK_fdset_isset (tc->read_ready,
-                                               fc->armClientSocket))
-    {
-      fc->client_to_service_task =
-       GNUNET_SCHEDULER_add_read_net (scheduler,
-                                      GNUNET_TIME_UNIT_FOREVER_REL,
-                                      fc->armClientSocket,
-                                      &receiveFromClient, fc);
-      return;
-    }
-  fc->client_to_service_bufferPos = fc->client_to_service_buffer;
-  fc->client_to_service_bufferDataLength =
-    GNUNET_NETWORK_socket_recv (fc->armClientSocket,
-                               fc->client_to_service_buffer, 
-                               BUFFER_SIZE);
-  if (fc->client_to_service_bufferDataLength <= 0)
-    {
-      if (fc->client_to_service_bufferDataLength == 0)
-       {
-#if DEBUG_SERVICE_MANAGER
-         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                     "Client closed connection with service `%s'\n",
-                     fc->listen_info->serviceName);
-#endif
-       }
-      else
-       {
-#if DEBUG_SERVICE_MANAGER
-         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                     "Error receiving from client: %s\n",
-                     STRERROR (errno));
-#endif
-       }
-      closeClientAndServiceSockets (fc, REASON_CLIENT_TO_SERVICE);
-      return;
-    }
-#if DEBUG_SERVICE_MANAGER
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-             "Received %d bytes for service\n",
-             fc->client_to_service_bufferDataLength);
-#endif
-  if (fc->armServiceSocket != NULL)        
-    fc->client_to_service_task = 
-      GNUNET_SCHEDULER_add_write_net (scheduler,
-                                     GNUNET_TIME_UNIT_FOREVER_REL,
-                                     fc->armServiceSocket,
-                                     &forwardToService, fc);
-}
-
-
-/**
- *
- */
-static void
-start_forwarding (void *cls,
-                 const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
-  struct ForwardedConnection *fc = cls;
-  struct GNUNET_TIME_Relative rem;
-
-  fc->start_task = GNUNET_SCHEDULER_NO_TASK;
-  if ( (NULL != tc) &&
-       (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) )
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                 _("Unable to forward to service `%s': shutdown\n"),
-                 fc->listen_info->serviceName);
-      closeClientAndServiceSockets (fc, REASON_ERROR);
-      return;
-    }
-  rem = GNUNET_TIME_absolute_get_remaining (fc->timeout);
-  if (rem.value == 0)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                 _("Unable to forward to service `%s': timeout before 
connect\n"),
-                 fc->listen_info->serviceName);
-      closeClientAndServiceSockets (fc, REASON_ERROR);
-      return;
-    }
-  fc->armServiceSocket =
-    GNUNET_NETWORK_socket_create (fc->listen_info->service_addr->sa_family,
-                                 SOCK_STREAM, 0);
-  if (NULL == fc->armServiceSocket)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                 _ ("Unable to start service `%s': %s\n"),
-                 fc->listen_info->serviceName,
-                 STRERROR (errno));
-      closeClientAndServiceSockets (fc, REASON_ERROR);
-      return;
-    }
-  if ( (GNUNET_SYSERR ==
-       GNUNET_NETWORK_socket_connect (fc->armServiceSocket,
-                                      fc->listen_info->service_addr,
-                                      fc->listen_info->service_addr_len)) &&
-       (errno != EINPROGRESS) )
-    {
-      GNUNET_break (GNUNET_OK ==
-                   GNUNET_NETWORK_socket_close (fc->armServiceSocket));
-      fc->armServiceSocket = NULL;
-      fc->back_off = GNUNET_TIME_relative_multiply (fc->back_off, 2);
-  #if DEBUG_SERVICE_MANAGER
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                 "Failed to connected to service `%s' at `%s', will try again 
in %llu ms\n",
-                 fc->listen_info->serviceName,
-                 GNUNET_a2s (fc->listen_info->service_addr,
-                             fc->listen_info->service_addr_len),
-                 (unsigned long long) GNUNET_TIME_relative_min (fc->back_off,
-                                                                rem).value);
-#endif
-      GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == fc->start_task);
-      fc->start_task
-       = GNUNET_SCHEDULER_add_delayed (scheduler,
-                                       GNUNET_TIME_relative_min (fc->back_off,
-                                                                 rem),
-                                       &start_forwarding,
-                                       fc);
-      return;
-    }
-#if DEBUG_SERVICE_MANAGER
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-             "Connected to service, now starting forwarding\n");
-#endif
-  if (fc->client_to_service_task == GNUNET_SCHEDULER_NO_TASK)
-    {
-      if (fc->client_to_service_bufferDataLength == 0) 
-       fc->client_to_service_task =
-         GNUNET_SCHEDULER_add_read_net (scheduler,
-                                        GNUNET_TIME_UNIT_FOREVER_REL,
-                                        fc->armClientSocket,
-                                        &receiveFromClient, fc);
-      else
-       fc->client_to_service_task = 
-         GNUNET_SCHEDULER_add_write_net (scheduler, 
-                                         GNUNET_TIME_UNIT_FOREVER_REL,
-                                         fc->armServiceSocket,
-                                         &forwardToService, fc);
-    }
-  if (fc->service_to_client_task == GNUNET_SCHEDULER_NO_TASK)
-    {
-      if (fc->service_to_client_bufferDataLength == 0) 
-       fc->service_to_client_task =
-         GNUNET_SCHEDULER_add_read_net (scheduler,
-                                        GNUNET_TIME_UNIT_FOREVER_REL,
-                                        fc->armServiceSocket,
-                                        &receiveFromService, fc);
-      else
-       fc->service_to_client_task = 
-         GNUNET_SCHEDULER_add_write_net (scheduler, 
-                                         GNUNET_TIME_UNIT_FOREVER_REL,
-                                         fc->armClientSocket,
-                                         &forwardToClient, fc);
-    }
-}
-
-
-
-/**
- *
- */
-int
-stop_listening (const char *serviceName)
-{
-  struct ServiceListeningInfo *pos;
-  struct ServiceListeningInfo *next;
-  int ret;
-  
-  ret = GNUNET_NO;
-  next = serviceListeningInfoList_head;
-  while (NULL != (pos = next))
-    {
-      next = pos->next;
-      if ( (serviceName != NULL) &&
-          (strcmp (pos->serviceName, serviceName) != 0) )
-       continue;
-      if (pos->acceptTask != GNUNET_SCHEDULER_NO_TASK)
-       GNUNET_SCHEDULER_cancel (scheduler, pos->acceptTask);
-      GNUNET_break (GNUNET_OK ==
-                   GNUNET_NETWORK_socket_close (pos->listeningSocket));
-      GNUNET_CONTAINER_DLL_remove (serviceListeningInfoList_head,
-                                  serviceListeningInfoList_tail, 
-                                  pos);
-      GNUNET_free (pos->serviceName);             
-      GNUNET_free (pos->service_addr);
-      GNUNET_free (pos); 
-      ret = GNUNET_OK;
-    }
-  return ret;
-}
-
-
-/**
- * First connection has come to the listening socket associated with the 
service,
- * create the service in order to relay the incoming connection to it
- * 
- * @param cls callback data, struct ServiceListeningInfo describing a listen 
socket
- * @param tc context 
- */
-static void
-acceptConnection (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
-  struct ServiceListeningInfo *serviceListeningInfo = cls;
-  struct ForwardedConnection *fc;
-
-  serviceListeningInfo->acceptTask = GNUNET_SCHEDULER_NO_TASK;
-  if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
-    return;
-  fc = GNUNET_malloc (sizeof (struct ForwardedConnection));
-  fc->listen_info = serviceListeningInfo;
-  fc->service_to_client_bufferPos = fc->service_to_client_buffer;
-  fc->client_to_service_bufferPos = fc->client_to_service_buffer;
-  fc->client_addr_len = sizeof (fc->client_addr);
-  fc->armClientSocket = GNUNET_NETWORK_socket_accept 
(serviceListeningInfo->listeningSocket,
-                                                     (struct sockaddr*) 
fc->client_addr,
-                                                     &fc->client_addr_len);
-  if (NULL == fc->armClientSocket)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                 _("Unable to accept connection for service `%s': %s\n"),
-                 serviceListeningInfo->serviceName,
-                 STRERROR (errno));
-      GNUNET_free (fc);
-      serviceListeningInfo->acceptTask =
-       GNUNET_SCHEDULER_add_read_net (scheduler,
-                                      GNUNET_TIME_UNIT_FOREVER_REL, 
-                                      serviceListeningInfo->listeningSocket,
-                                      &acceptConnection,
-                                      serviceListeningInfo);
-      return;
-    }
-  GNUNET_break (GNUNET_OK ==
-               GNUNET_NETWORK_socket_close 
(serviceListeningInfo->listeningSocket));
-  GNUNET_CONTAINER_DLL_remove (serviceListeningInfoList_head,
-                              serviceListeningInfoList_tail, 
-                              serviceListeningInfo);
-  start_service (NULL, serviceListeningInfo->serviceName);
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO, 
-             _("Service `%s' started\n"),
-             fc->listen_info->serviceName);
-  fc->timeout = GNUNET_TIME_relative_to_absolute 
(GNUNET_CONSTANTS_SERVICE_TIMEOUT);
-  fc->back_off = GNUNET_TIME_UNIT_MILLISECONDS;
-  fc->client_to_service_task =
-    GNUNET_SCHEDULER_add_read_net (scheduler,
-                                  GNUNET_TIME_UNIT_FOREVER_REL,
-                                  fc->armClientSocket,
-                                  &receiveFromClient, fc);
-  GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == fc->start_task);
-  fc->start_task 
-    = GNUNET_SCHEDULER_add_now (scheduler,
-                               &start_forwarding,
-                               fc);
-}
-
-
-/**
- * Creating a listening socket for each of the service's addresses and
- * wait for the first incoming connection to it
- * 
- * @param sa address associated with the service
- * @param addr_len length of sa
- * @param serviceName the name of the service in question
- */
-static void
-createListeningSocket (struct sockaddr *sa, 
-                      socklen_t addr_len,
-                      const char *serviceName)
-{
-  const static int on = 1;
-  struct GNUNET_NETWORK_Handle *sock;
-  struct ServiceListeningInfo *serviceListeningInfo;
-
-  switch (sa->sa_family)
-    {
-    case AF_INET:
-      sock = GNUNET_NETWORK_socket_create (PF_INET, SOCK_STREAM, 0);
-      break;
-    case AF_INET6:
-      sock = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0);
-      break;
-    default:
-      sock = NULL;
-      break;
-    }
-  if (NULL == sock)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                 _("Unable to create socket for service `%s'"),
-                 serviceName);
-      GNUNET_free (sa);
-      return;
-    }
-  if (GNUNET_NETWORK_socket_setsockopt
-      (sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) != GNUNET_OK)
-    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
-                         "setsockopt");
-#ifdef IPV6_V6ONLY
-  if ( (sa->sa_family == AF_INET6) &&
-       (GNUNET_NETWORK_socket_setsockopt
-       (sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on)) != GNUNET_OK))
-    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
-                        "setsockopt");
-#endif
-
-  if (GNUNET_NETWORK_socket_bind
-      (sock, (const struct sockaddr *) sa, addr_len) != GNUNET_OK)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                 _("Unable to bind listening socket for service `%s' to 
address `%s': %s\n"),
-                 serviceName,
-                 GNUNET_a2s (sa, addr_len),
-                 STRERROR (errno));
-      GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
-      GNUNET_free (sa);
-      return;
-    }
-  if (GNUNET_NETWORK_socket_listen (sock, 5) != GNUNET_OK)
-    {
-      GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
-                          "listen");
-      GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
-      GNUNET_free (sa);
-      return;
-    }
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-             _("ARM now monitors connections to service `%s' at `%s'\n"),
-             serviceName,
-             GNUNET_a2s (sa, addr_len));
-  serviceListeningInfo = GNUNET_malloc (sizeof (struct ServiceListeningInfo));
-  serviceListeningInfo->serviceName = GNUNET_strdup (serviceName);
-  serviceListeningInfo->service_addr = sa;
-  serviceListeningInfo->service_addr_len = addr_len;
-  serviceListeningInfo->listeningSocket = sock;
-  serviceListeningInfo->acceptTask =
-    GNUNET_SCHEDULER_add_read_net (scheduler,
-                                  GNUNET_TIME_UNIT_FOREVER_REL, sock,
-                                  &acceptConnection,
-                                  serviceListeningInfo);
-  GNUNET_CONTAINER_DLL_insert (serviceListeningInfoList_head,
-                              serviceListeningInfoList_tail,
-                              serviceListeningInfo);
-}
-
-
-/**
- * Callback function, checks whether the current tokens are representing a 
service,
- * gets its addresses and create listening socket for it.
- * 
- * @param cls callback data, not used
- * @param section configuration section
- * @param option configuration option
- * @param value the option's value
- */
-static void
-checkPortNumberCB (void *cls,
-                  const char *section, 
-                  const char *option, 
-                  const char *value)
-{
-  struct sockaddr **addrs;
-  socklen_t *addr_lens;
-  int ret;
-  unsigned int i;
-  
-  if ( (strcasecmp (section, "arm") == 0) ||
-       (strcasecmp (option, "AUTOSTART") != 0) ||
-       (strcasecmp (value, "YES") != 0) ||
-       (isInDefaultList (section) == GNUNET_YES) )
-    return;
-  if (0 >= (ret = GNUNET_SERVICE_get_server_addresses (section, cfg, &addrs,
-                                                      &addr_lens)))
-    return;
-  /* this will free (or capture) addrs[i] */
-  for (i = 0; i < ret; i++)
-    createListeningSocket (addrs[i], addr_lens[i], section);
-  GNUNET_free (addrs);
-  GNUNET_free (addr_lens);
-}
-
-
-/**
- * Entry point to the Service Manager
- *
- * @param configurationHandle configuration to use to get services
- * @param sched scheduler to handle clients and services communications
- */
-void
-prepareServices (const struct GNUNET_CONFIGURATION_Handle
-                *configurationHandle, struct GNUNET_SCHEDULER_Handle *sched)
-{
-  char *defaultServicesString;
-
-  scheduler = sched;
-  cfg = configurationHandle;
-  /* Split the default services into a list */
-  if (GNUNET_OK ==
-      GNUNET_CONFIGURATION_get_value_string (cfg, "arm", "DEFAULTSERVICES",
-                                            &defaultServicesString))
-    {
-      addDefaultServicesToList (defaultServicesString);
-      GNUNET_free (defaultServicesString);    
-    }
-  /* Spot the services from the configuration and create a listening
-     socket for each */
-  GNUNET_CONFIGURATION_iterate (cfg, &checkPortNumberCB, NULL);
-}
-
-/* end of gnunet-service-manager.c */

Deleted: gnunet/src/arm/gnunet_service_arm_.h
===================================================================
--- gnunet/src/arm/gnunet_service_arm_.h        2010-05-25 16:42:39 UTC (rev 
11513)
+++ gnunet/src/arm/gnunet_service_arm_.h        2010-05-25 16:44:26 UTC (rev 
11514)
@@ -1,46 +0,0 @@
-/*
-     This file is part of GNUnet.
-     (C) 2010 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 2, 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.
-*/
-
-/**
- * @file arm/gnunet_service_arm_.h
- * @brief function prototypes for gnunet_service_arm.c, and 
gnunet_service_manager.c
- * @author Safey Abdel Halim
- */
-
-#ifndef GNUNET_SERVICE_ARM__H
-#define GNUNET_SERVICE_ARM__H
-
-void start_service (struct GNUNET_SERVER_Client *client,
-                   const char *servicename);
-
-/**
- * Stop listening for connections to a service.
- * 
- * @param serviceName name of service to stop listening for
- * @return GNUNET_OK if we stopped to listen, GNUNET_NO if we were
- *         not listening
- */
-int stop_listening (const char *serviceName);
-
-void prepareServices (const struct GNUNET_CONFIGURATION_Handle
-                     *configurationHandle,
-                     struct GNUNET_SCHEDULER_Handle *sched);
-
-#endif




reply via email to

[Prev in Thread] Current Thread [Next in Thread]