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
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;
{
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
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 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;
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,
}
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);
}
+/**
+ * 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