X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Futil%2Fservice.c;h=80d18d8f128f4967e2e258c2da9f482d7bfa261c;hb=65f518e8036699fa3c574266d39e3cd1263af9e8;hp=752dd2a74820c78dd7ed1edb5c1a81eb01a8527b;hpb=13f63dab5a87cb8b95b8d77f11925a7c7429038b;p=oweals%2Fgnunet.git diff --git a/src/util/service.c b/src/util/service.c index 752dd2a74..80d18d8f1 100644 --- a/src/util/service.c +++ b/src/util/service.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2009, 2012 Christian Grothoff (and other contributing authors) + Copyright (C) 2009, 2012 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 @@ -28,6 +28,7 @@ #include "gnunet_protocols.h" #include "gnunet_constants.h" #include "gnunet_resolver_service.h" +#include "speedup.h" #if HAVE_MALLINFO #include @@ -44,22 +45,6 @@ /* ******************* 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,10 +462,14 @@ 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 + * parameter is ignore on systems other than LINUX */ static void -add_unixpath (struct sockaddr **saddrs, socklen_t * saddrlens, - const char *unixpath) +add_unixpath (struct sockaddr **saddrs, + socklen_t *saddrlens, + const char *unixpath, + int abstract) { #ifdef AF_UNIX struct sockaddr_un *un; @@ -486,6 +477,10 @@ add_unixpath (struct sockaddr **saddrs, socklen_t * saddrlens, un = GNUNET_new (struct sockaddr_un); un->sun_family = AF_UNIX; strncpy (un->sun_path, unixpath, sizeof (un->sun_path) - 1); +#ifdef LINUX + if (GNUNET_YES == abstract) + un->sun_path[0] = '\0'; +#endif #if HAVE_SOCKADDR_IN_SIN_LEN un->sun_len = (u_char) sizeof (struct sockaddr_un); #endif @@ -509,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 @@ -521,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; @@ -536,6 +531,7 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name, unsigned int i; int resi; int ret; + int abstract; struct sockaddr **saddrs; socklen_t *saddrlens; char *hostname; @@ -553,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); @@ -566,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; } @@ -608,6 +603,7 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name, hostname = NULL; unixpath = NULL; + abstract = GNUNET_NO; #ifdef AF_UNIX if ((GNUNET_YES == GNUNET_CONFIGURATION_have_value (cfg, service_name, "UNIXPATH")) && @@ -626,10 +622,19 @@ 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); } - if (GNUNET_OK != - GNUNET_DISK_directory_create_for_file (unixpath)) +#ifdef LINUX + abstract = GNUNET_CONFIGURATION_get_value_yesno (cfg, + "TESTING", + "USE_ABSTRACT_SOCKETS"); + if (GNUNET_SYSERR == abstract) + abstract = GNUNET_NO; +#endif + if ((GNUNET_YES != abstract) + && (GNUNET_OK != + GNUNET_DISK_directory_create_for_file (unixpath))) GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "mkdir", unixpath); @@ -649,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; } @@ -673,7 +679,7 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name, { saddrs = GNUNET_malloc (2 * sizeof (struct sockaddr *)); saddrlens = GNUNET_malloc (2 * sizeof (socklen_t)); - add_unixpath (saddrs, saddrlens, unixpath); + add_unixpath (saddrs, saddrlens, unixpath, abstract); GNUNET_free_non_null (unixpath); GNUNET_free_non_null (hostname); *addrs = saddrs; @@ -684,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); @@ -710,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); @@ -725,7 +736,7 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name, i = 0; if (NULL != unixpath) { - add_unixpath (saddrs, saddrlens, unixpath); + add_unixpath (saddrs, saddrlens, unixpath, abstract); i++; } next = res; @@ -777,7 +788,7 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name, saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t)); if (NULL != unixpath) { - add_unixpath (saddrs, saddrlens, unixpath); + add_unixpath (saddrs, saddrlens, unixpath, abstract); i++; } saddrlens[i] = sizeof (struct sockaddr_in); @@ -799,7 +810,7 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name, i = 0; if (NULL != unixpath) { - add_unixpath (saddrs, saddrlens, unixpath); + add_unixpath (saddrs, saddrlens, unixpath, abstract); i++; } saddrlens[i] = sizeof (struct sockaddr_in6); @@ -1118,12 +1129,13 @@ write_pid_file (struct GNUNET_SERVICE_Context *sctx, pid_t pid) * @param tc unused */ static void -shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +shutdown_task (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) { 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 @@ -1168,7 +1180,8 @@ service_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) #ifndef WINDOWS if (NULL != sctx->addrs) for (i = 0; NULL != sctx->addrs[i]; i++) - if (AF_UNIX == sctx->addrs[i]->sa_family) + if ((AF_UNIX == sctx->addrs[i]->sa_family) + && ('\0' != ((const struct sockaddr_un *)sctx->addrs[i])->sun_path[0])) GNUNET_DISK_fix_permissions (((const struct sockaddr_un *)sctx->addrs[i])->sun_path, sctx->match_uid, sctx->match_gid); @@ -1441,12 +1454,24 @@ GNUNET_SERVICE_run (int argc, char *const *argv, HANDLE_ERROR; if (NULL == opt_cfg_fn) opt_cfg_fn = GNUNET_strdup (cfg_fn); - if (GNUNET_YES == - GNUNET_DISK_file_test (opt_cfg_fn)) - (void) GNUNET_CONFIGURATION_load (cfg, opt_cfg_fn); + if (GNUNET_YES == GNUNET_DISK_file_test (opt_cfg_fn)) + { + if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, opt_cfg_fn)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Malformed configuration file `%s', exit ...\n"), + opt_cfg_fn); + goto shutdown; + } + } else { - (void) GNUNET_CONFIGURATION_load (cfg, NULL); + if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, NULL)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Malformed configuration, exit ...\n")); + goto shutdown; + } if (0 != strcmp (opt_cfg_fn, cfg_fn)) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not access configuration file `%s'\n"), @@ -1519,7 +1544,7 @@ shutdown: GNUNET_free_non_null (logfile); GNUNET_free_non_null (loglev); GNUNET_free (cfg_fn); - GNUNET_free (opt_cfg_fn); + GNUNET_free_non_null (opt_cfg_fn); GNUNET_free_non_null (sctx.v4_denied); GNUNET_free_non_null (sctx.v6_denied); GNUNET_free_non_null (sctx.v4_allowed); @@ -1577,7 +1602,8 @@ GNUNET_SERVICE_start (const char *service_name, #ifndef WINDOWS if (NULL != sctx->addrs) for (i = 0; NULL != sctx->addrs[i]; i++) - if (AF_UNIX == sctx->addrs[i]->sa_family) + if ((AF_UNIX == sctx->addrs[i]->sa_family) + && ('\0' != ((const struct sockaddr_un *)sctx->addrs[i])->sun_path[0])) GNUNET_DISK_fix_permissions (((const struct sockaddr_un *)sctx->addrs[i])->sun_path, sctx->match_uid, sctx->match_gid); @@ -1606,6 +1632,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". * @@ -1636,10 +1676,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);