fix
[oweals/gnunet.git] / src / arm / gnunet-service-arm_interceptor.c
index afefe4e482e585273ca1f3f107e9cdaba1ad644c..bc0c260a4f9c803379a1b409ad953c0e2c83c4e3 100644 (file)
@@ -4,7 +4,7 @@
 
      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
+     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
@@ -474,14 +474,14 @@ receiveFromService (void *cls,
                                BUFFER_SIZE);
   if (fc->service_to_client_bufferDataLength <= 0)
     {
+#if DEBUG_SERVICE_MANAGER
       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
        }
+#endif
       if (fc->first_write_done != GNUNET_YES)
        {
          fc->service_to_client_bufferDataLength = 0;
@@ -493,7 +493,7 @@ receiveFromService (void *cls,
            {
              GNUNET_SCHEDULER_cancel (scheduler,
                                       fc->client_to_service_task);
-             fc->service_to_client_task = GNUNET_SCHEDULER_NO_TASK;
+             fc->client_to_service_task = GNUNET_SCHEDULER_NO_TASK;
            }
          fc->back_off = GNUNET_TIME_relative_multiply (fc->back_off, 2);
 #if DEBUG_SERVICE_MANAGER
@@ -847,7 +847,6 @@ stop_listening (const char *serviceName)
   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
@@ -856,14 +855,14 @@ stop_listening (const char *serviceName)
  * @param tc context 
  */
 static void
-acceptConnection (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+acceptConnection (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
+
+
+static void
+accept_and_forward (struct ServiceListeningInfo *serviceListeningInfo)
 {
-  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;
@@ -879,6 +878,9 @@ acceptConnection (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
                  serviceListeningInfo->serviceName,
                  STRERROR (errno));
       GNUNET_free (fc);
+      GNUNET_CONTAINER_DLL_insert (serviceListeningInfoList_head,
+                                  serviceListeningInfoList_tail, 
+                                  serviceListeningInfo); 
       serviceListeningInfo->acceptTask =
        GNUNET_SCHEDULER_add_read_net (scheduler,
                                       GNUNET_TIME_UNIT_FOREVER_REL, 
@@ -889,10 +891,7 @@ acceptConnection (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
     }
   GNUNET_break (GNUNET_OK ==
                GNUNET_NETWORK_socket_close (serviceListeningInfo->listeningSocket));
-  GNUNET_CONTAINER_DLL_remove (serviceListeningInfoList_head,
-                              serviceListeningInfoList_tail, 
-                              serviceListeningInfo);
-  start_service (NULL, serviceListeningInfo->serviceName);
+  start_service (NULL, serviceListeningInfo->serviceName, NULL);
   GNUNET_log (GNUNET_ERROR_TYPE_INFO, 
              _("Service `%s' started\n"),
              fc->listen_info->serviceName);
@@ -911,6 +910,84 @@ acceptConnection (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 }
 
 
+/**
+ * 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 *sli = cls;
+  struct ServiceListeningInfo *pos;
+  struct ServiceListeningInfo *next;
+  int *lsocks;
+  unsigned int ls;
+  int use_lsocks;
+
+  sli->acceptTask = GNUNET_SCHEDULER_NO_TASK;
+  if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
+    return;
+  GNUNET_CONTAINER_DLL_remove (serviceListeningInfoList_head,
+                              serviceListeningInfoList_tail, 
+                              sli);  
+#ifndef MINGW
+  use_lsocks = GNUNET_NO;
+  if (GNUNET_YES == GNUNET_CONFIGURATION_have_value (cfg,
+                                                    sli->serviceName,
+                                                    "DISABLE_SOCKET_FORWARDING"))
+    use_lsocks = GNUNET_CONFIGURATION_get_value_yesno (cfg,
+                                                      sli->serviceName,
+                                                      "DISABLE_SOCKET_FORWARDING");
+#else
+  use_lsocks = GNUNET_YES;
+#endif
+  if (GNUNET_NO != use_lsocks)
+    {
+      accept_and_forward (sli);
+      return;
+    }
+  lsocks = NULL;
+  ls = 0;
+  next = serviceListeningInfoList_head;
+  while (NULL != (pos = next))
+    {
+      next = pos->next;
+      if (0 == strcmp (pos->serviceName,
+                      sli->serviceName))
+       {
+         GNUNET_array_append (lsocks, ls, 
+                              GNUNET_NETWORK_get_fd (pos->listeningSocket));     
+         GNUNET_free (pos->listeningSocket); /* deliberately no closing! */
+         GNUNET_free (pos->service_addr);
+         GNUNET_free (pos->serviceName);
+         GNUNET_SCHEDULER_cancel (scheduler,
+                                  pos->acceptTask);
+         GNUNET_CONTAINER_DLL_remove (serviceListeningInfoList_head,
+                                      serviceListeningInfoList_tail, 
+                                      pos);
+         GNUNET_free (pos);
+       }
+    }
+  GNUNET_array_append (lsocks, ls, 
+                      GNUNET_NETWORK_get_fd (sli->listeningSocket));
+  GNUNET_free (sli->listeningSocket); /* deliberately no closing! */
+  GNUNET_free (sli->service_addr);
+  GNUNET_array_append (lsocks, ls, -1);
+  start_service (NULL, 
+                sli->serviceName,
+                lsocks);
+  ls = 0;
+  while (lsocks[ls] != -1)
+    GNUNET_break (0 == close (lsocks[ls++]));      
+  GNUNET_array_grow (lsocks, ls, 0);
+  GNUNET_free (sli->serviceName);
+  GNUNET_free (sli); 
+}
+
+
 /**
  * Creating a listening socket for each of the service's addresses and
  * wait for the first incoming connection to it