Merge branch 'master' of ssh://gnunet.org/gnunet
[oweals/gnunet.git] / src / util / service.c
index deb0be46b531f1c96c89ac553e0829de4d0593c3..496904fb1f5d7ac1926fc32920035eb7fdcb79c4 100644 (file)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     (C) 2009, 2012 Christian Grothoff (and other contributing authors)
+     Copyright (C) 2009, 2012 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
@@ -14,8 +14,8 @@
 
      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.
+     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+     Boston, MA 02110-1301, USA.
 */
 
 /**
@@ -28,6 +28,7 @@
 #include "gnunet_protocols.h"
 #include "gnunet_constants.h"
 #include "gnunet_resolver_service.h"
+#include "speedup.h"
 
 #if HAVE_MALLINFO
 #include <malloc.h>
 #endif
 
 
-#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
+#define LOG(kind,...) GNUNET_log_from (kind, "util-service", __VA_ARGS__)
 
-#define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall)
+#define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-service", syscall)
 
-#define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename)
+#define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util-service", syscall, filename)
 
 
 /* ******************* access control ******************** */
 
-/**
- * Start task that may speed up our system clock artificially
- *
- * @param cfg configuration to use
- * @return GNUNET_OK on success, GNUNET_SYSERR if the speedup was not configured
- */
-int
-GNUNET_SPEEDUP_start_ (const struct GNUNET_CONFIGURATION_Handle *cfg);
-
-/**
- * Stop tasks that modify clock behavior.
- */
-void
-GNUNET_SPEEDUP_stop_ (void);
-
-
 /**
  * Check if the given IP address is in the list of IP addresses.
  *
@@ -157,7 +142,7 @@ struct GNUNET_SERVICE_Context
   GNUNET_SERVICE_Main task;
 
   /**
-   * Closure for task.
+   * Closure for @e task.
    */
   void *task_cls;
 
@@ -202,7 +187,7 @@ struct GNUNET_SERVICE_Context
   /**
    * Task ID of the shutdown task.
    */
-  GNUNET_SCHEDULER_TaskIdentifier shutdown_task;
+  struct GNUNET_SCHEDULER_Task *shutdown_task;
 
   /**
    * Idle timeout for server.
@@ -404,7 +389,8 @@ get_pid_file_name (struct GNUNET_SERVICE_Context *sctx)
  *         no ACL configured)
  */
 static int
-process_acl4 (struct GNUNET_STRINGS_IPv4NetworkPolicy **ret, struct GNUNET_SERVICE_Context *sctx,
+process_acl4 (struct GNUNET_STRINGS_IPv4NetworkPolicy **ret,
+              struct GNUNET_SERVICE_Context *sctx,
               const char *option)
 {
   char *opt;
@@ -441,7 +427,8 @@ process_acl4 (struct GNUNET_STRINGS_IPv4NetworkPolicy **ret, struct GNUNET_SERVI
  *         no ACL configured)
  */
 static int
-process_acl6 (struct GNUNET_STRINGS_IPv6NetworkPolicy **ret, struct GNUNET_SERVICE_Context *sctx,
+process_acl6 (struct GNUNET_STRINGS_IPv6NetworkPolicy **ret,
+              struct GNUNET_SERVICE_Context *sctx,
               const char *option)
 {
   char *opt;
@@ -475,11 +462,12 @@ process_acl6 (struct GNUNET_STRINGS_IPv6NetworkPolicy **ret, struct GNUNET_SERVI
  * @param saddrs array to update
  * @param saddrlens where to store the address length
  * @param unixpath path to add
- * @param abstract GNUNET_YES to add an abstract UNIX domain socket.  This
+ * @param abstract #GNUNET_YES to add an abstract UNIX domain socket.  This
  *          parameter is ignore on systems other than LINUX
  */
 static void
-add_unixpath (struct sockaddr **saddrs, socklen_t * saddrlens,
+add_unixpath (struct sockaddr **saddrs,
+              socklen_t *saddrlens,
               const char *unixpath,
               int abstract)
 {
@@ -493,7 +481,7 @@ add_unixpath (struct sockaddr **saddrs, socklen_t * saddrlens,
   if (GNUNET_YES == abstract)
     un->sun_path[0] = '\0';
 #endif
-#if HAVE_SOCKADDR_IN_SIN_LEN
+#if HAVE_SOCKADDR_UN_SUN_LEN
   un->sun_len = (u_char) sizeof (struct sockaddr_un);
 #endif
   *saddrs = (struct sockaddr *) un;
@@ -516,7 +504,7 @@ add_unixpath (struct sockaddr **saddrs, socklen_t * saddrlens,
  *              addresses the server should bind to and listen on; the
  *              array will be NULL-terminated (on success)
  * @param addr_lens set (call by reference) to an array of the lengths
- *              of the respective 'struct sockaddr' struct in the 'addrs'
+ *              of the respective `struct sockaddr` struct in the @a addrs
  *              array (on success)
  * @return number of addresses found on success,
  *              #GNUNET_SYSERR if the configuration
@@ -528,8 +516,8 @@ add_unixpath (struct sockaddr **saddrs, socklen_t * saddrlens,
  */
 int
 GNUNET_SERVICE_get_server_addresses (const char *service_name,
-                                     const struct GNUNET_CONFIGURATION_Handle
-                                     *cfg, struct sockaddr ***addrs,
+                                     const struct GNUNET_CONFIGURATION_Handle *cfg,
+                                     struct sockaddr ***addrs,
                                      socklen_t ** addr_lens)
 {
   int disablev6;
@@ -561,7 +549,7 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name,
   else
     disablev6 = GNUNET_NO;
 
-  if (!disablev6)
+  if (! disablev6)
   {
     /* probe IPv6 support */
     desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0);
@@ -574,8 +562,7 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name,
         return GNUNET_SYSERR;
       }
       LOG (GNUNET_ERROR_TYPE_INFO,
-           _
-           ("Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n"),
+           _("Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n"),
            service_name, STRERROR (errno));
       disablev6 = GNUNET_YES;
     }
@@ -635,7 +622,8 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name,
            (unsigned long long) sizeof (s_un.sun_path));
       unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath);
       LOG (GNUNET_ERROR_TYPE_INFO,
-          _("Using `%s' instead\n"), unixpath);
+          _("Using `%s' instead\n"),
+           unixpath);
     }
 #ifdef LINUX
     abstract = GNUNET_CONFIGURATION_get_value_yesno (cfg,
@@ -666,7 +654,8 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name,
       }
       LOG (GNUNET_ERROR_TYPE_INFO,
            _("Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"),
-           service_name, STRERROR (errno));
+           service_name,
+           STRERROR (errno));
       GNUNET_free (unixpath);
       unixpath = NULL;
     }
@@ -701,16 +690,19 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name,
   if (NULL != hostname)
   {
     LOG (GNUNET_ERROR_TYPE_DEBUG,
-         "Resolving `%s' since that is where `%s' will bind to.\n", hostname,
+         "Resolving `%s' since that is where `%s' will bind to.\n",
+         hostname,
          service_name);
     memset (&hints, 0, sizeof (struct addrinfo));
     if (disablev6)
       hints.ai_family = AF_INET;
     hints.ai_protocol = IPPROTO_TCP;
     if ((0 != (ret = getaddrinfo (hostname, NULL, &hints, &res))) ||
-        (res == NULL))
+        (NULL == res))
     {
-      LOG (GNUNET_ERROR_TYPE_ERROR, _("Failed to resolve `%s': %s\n"), hostname,
+      LOG (GNUNET_ERROR_TYPE_ERROR,
+           _("Failed to resolve `%s': %s\n"),
+           hostname,
            gai_strerror (ret));
       GNUNET_free (hostname);
       GNUNET_free_non_null (unixpath);
@@ -727,8 +719,10 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name,
     }
     if (0 == i)
     {
-      LOG (GNUNET_ERROR_TYPE_ERROR, _("Failed to find %saddress for `%s'.\n"),
-           disablev6 ? "IPv4 " : "", hostname);
+      LOG (GNUNET_ERROR_TYPE_ERROR,
+           _("Failed to find %saddress for `%s'.\n"),
+           disablev6 ? "IPv4 " : "",
+           hostname);
       freeaddrinfo (res);
       GNUNET_free (hostname);
       GNUNET_free_non_null (unixpath);
@@ -762,7 +756,7 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name,
         GNUNET_assert (sizeof (struct sockaddr_in) == pos->ai_addrlen);
         saddrlens[i] = pos->ai_addrlen;
         saddrs[i] = GNUNET_malloc (saddrlens[i]);
-        memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
+        GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
         ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
       }
       else
@@ -771,7 +765,7 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name,
         GNUNET_assert (sizeof (struct sockaddr_in6) == pos->ai_addrlen);
         saddrlens[i] = pos->ai_addrlen;
         saddrs[i] = GNUNET_malloc (saddrlens[i]);
-        memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
+        GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
         ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
       }
       i++;
@@ -1132,15 +1126,14 @@ write_pid_file (struct GNUNET_SERVICE_Context *sctx, pid_t pid)
  * Task run during shutdown.  Stops the server/service.
  *
  * @param cls the `struct GNUNET_SERVICE_Context`
- * @param tc unused
  */
 static void
-shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+shutdown_task (void *cls)
 {
   struct GNUNET_SERVICE_Context *service = cls;
   struct GNUNET_SERVER_Handle *server = service->server;
 
-  service->shutdown_task = GNUNET_SCHEDULER_NO_TASK;
+  service->shutdown_task = NULL;
   if (0 != (service->options & GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN))
     GNUNET_SERVER_stop_listening (server);
   else
@@ -1152,16 +1145,13 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
  * Initial task for the service.
  *
  * @param cls service context
- * @param tc unused
  */
 static void
-service_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+service_task (void *cls)
 {
   struct GNUNET_SERVICE_Context *sctx = cls;
   unsigned int i;
 
-  if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
-    return;
   (void) GNUNET_SPEEDUP_start_ (sctx->cfg);
   GNUNET_RESOLVER_connect (sctx->cfg);
   if (NULL != sctx->lsocks)
@@ -1197,12 +1187,11 @@ service_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
   {
     /* install a task that will kill the server
      * process if the scheduler ever gets a shutdown signal */
-    sctx->shutdown_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
-                                                        &shutdown_task,
-                                                       sctx);
+    sctx->shutdown_task = GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
+                                                        sctx);
   }
   sctx->my_handlers = GNUNET_malloc (sizeof (defhandlers));
-  memcpy (sctx->my_handlers, defhandlers, sizeof (defhandlers));
+  GNUNET_memcpy (sctx->my_handlers, defhandlers, sizeof (defhandlers));
   i = 0;
   while (NULL != sctx->my_handlers[i].callback)
     sctx->my_handlers[i++].callback_cls = sctx;
@@ -1433,9 +1422,9 @@ GNUNET_SERVICE_run (int argc, char *const *argv,
                      "%s%s%s",
                      xdg,
                      DIR_SEPARATOR_STR,
-                     "gnunet.conf");
+                     GNUNET_OS_project_data_get ()->config_file);
   else
-    cfg_fn = GNUNET_strdup (GNUNET_DEFAULT_USER_CONFIG_FILE);
+    cfg_fn = GNUNET_strdup (GNUNET_OS_project_data_get ()->user_config_file);
   memset (&sctx, 0, sizeof (sctx));
   sctx.options = options;
   sctx.ready_confirm_fd = -1;
@@ -1614,7 +1603,7 @@ GNUNET_SERVICE_start (const char *service_name,
                                      sctx->match_gid);
 #endif
   sctx->my_handlers = GNUNET_malloc (sizeof (defhandlers));
-  memcpy (sctx->my_handlers, defhandlers, sizeof (defhandlers));
+  GNUNET_memcpy (sctx->my_handlers, defhandlers, sizeof (defhandlers));
   i = 0;
   while ((sctx->my_handlers[i].callback != NULL))
     sctx->my_handlers[i++].callback_cls = sctx;
@@ -1637,6 +1626,20 @@ GNUNET_SERVICE_get_server (struct GNUNET_SERVICE_Context *ctx)
 }
 
 
+/**
+ * Get the NULL-terminated array of listen sockets for this service.
+ *
+ * @param ctx service context to query
+ * @return NULL if there are no listen sockets, otherwise NULL-terminated
+ *              array of listen sockets.
+ */
+struct GNUNET_NETWORK_Handle *const*
+GNUNET_SERVICE_get_listen_sockets (struct GNUNET_SERVICE_Context *ctx)
+{
+  return ctx->lsocks;
+}
+
+
 /**
  * Stop a service that was started with "GNUNET_SERVICE_start".
  *
@@ -1667,10 +1670,10 @@ GNUNET_SERVICE_stop (struct GNUNET_SERVICE_Context *sctx)
     }
   }
 #endif
-  if (GNUNET_SCHEDULER_NO_TASK != sctx->shutdown_task)
+  if (NULL != sctx->shutdown_task)
   {
     GNUNET_SCHEDULER_cancel (sctx->shutdown_task);
-    sctx->shutdown_task = GNUNET_SCHEDULER_NO_TASK;
+    sctx->shutdown_task = NULL;
   }
   if (NULL != sctx->server)
     GNUNET_SERVER_destroy (sctx->server);