rps.conf is generated from rps.conf.in
[oweals/gnunet.git] / src / util / service.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2009, 2012 GNUnet e.V.
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18      Boston, MA 02110-1301, USA.
19 */
20
21 /**
22  * @file util/service.c
23  * @brief functions related to starting services
24  * @author Christian Grothoff
25  */
26 #include "platform.h"
27 #include "gnunet_util_lib.h"
28 #include "gnunet_protocols.h"
29 #include "gnunet_constants.h"
30 #include "gnunet_resolver_service.h"
31 #include "speedup.h"
32
33 #if HAVE_MALLINFO
34 #include <malloc.h>
35 #include "gauger.h"
36 #endif
37
38
39 #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
40
41 #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall)
42
43 #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename)
44
45
46 /* ******************* access control ******************** */
47
48 /**
49  * Check if the given IP address is in the list of IP addresses.
50  *
51  * @param list a list of networks
52  * @param add the IP to check (in network byte order)
53  * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is
54  */
55 static int
56 check_ipv4_listed (const struct GNUNET_STRINGS_IPv4NetworkPolicy *list,
57                    const struct in_addr *add)
58 {
59   unsigned int i;
60
61   if (NULL == list)
62     return GNUNET_NO;
63   i = 0;
64   while ((list[i].network.s_addr != 0) || (list[i].netmask.s_addr != 0))
65   {
66     if ((add->s_addr & list[i].netmask.s_addr) ==
67         (list[i].network.s_addr & list[i].netmask.s_addr))
68       return GNUNET_YES;
69     i++;
70   }
71   return GNUNET_NO;
72 }
73
74
75 /**
76  * Check if the given IP address is in the list of IP addresses.
77  *
78  * @param list a list of networks
79  * @param ip the IP to check (in network byte order)
80  * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is
81  */
82 static int
83 check_ipv6_listed (const struct GNUNET_STRINGS_IPv6NetworkPolicy *list,
84                    const struct in6_addr *ip)
85 {
86   unsigned int i;
87   unsigned int j;
88   struct in6_addr zero;
89
90   if (NULL == list)
91     return GNUNET_NO;
92   memset (&zero, 0, sizeof (struct in6_addr));
93   i = 0;
94 NEXT:
95   while (0 != memcmp (&zero, &list[i].network, sizeof (struct in6_addr)))
96   {
97     for (j = 0; j < sizeof (struct in6_addr) / sizeof (int); j++)
98       if (((((int *) ip)[j] & ((int *) &list[i].netmask)[j])) !=
99           (((int *) &list[i].network)[j] & ((int *) &list[i].netmask)[j]))
100       {
101         i++;
102         goto NEXT;
103       }
104     return GNUNET_YES;
105   }
106   return GNUNET_NO;
107 }
108
109
110 /* ****************** service struct ****************** */
111
112
113 /**
114  * Context for "service_task".
115  */
116 struct GNUNET_SERVICE_Context
117 {
118   /**
119    * Our configuration.
120    */
121   const struct GNUNET_CONFIGURATION_Handle *cfg;
122
123   /**
124    * Handle for the server.
125    */
126   struct GNUNET_SERVER_Handle *server;
127
128   /**
129    * NULL-terminated array of addresses to bind to, NULL if we got pre-bound
130    * listen sockets.
131    */
132   struct sockaddr **addrs;
133
134   /**
135    * Name of our service.
136    */
137   const char *service_name;
138
139   /**
140    * Main service-specific task to run.
141    */
142   GNUNET_SERVICE_Main task;
143
144   /**
145    * Closure for @e task.
146    */
147   void *task_cls;
148
149   /**
150    * IPv4 addresses that are not allowed to connect.
151    */
152   struct GNUNET_STRINGS_IPv4NetworkPolicy *v4_denied;
153
154   /**
155    * IPv6 addresses that are not allowed to connect.
156    */
157   struct GNUNET_STRINGS_IPv6NetworkPolicy *v6_denied;
158
159   /**
160    * IPv4 addresses that are allowed to connect (if not
161    * set, all are allowed).
162    */
163   struct GNUNET_STRINGS_IPv4NetworkPolicy *v4_allowed;
164
165   /**
166    * IPv6 addresses that are allowed to connect (if not
167    * set, all are allowed).
168    */
169   struct GNUNET_STRINGS_IPv6NetworkPolicy *v6_allowed;
170
171   /**
172    * My (default) message handlers.  Adjusted copy
173    * of "defhandlers".
174    */
175   struct GNUNET_SERVER_MessageHandler *my_handlers;
176
177   /**
178    * Array of the lengths of the entries in addrs.
179    */
180   socklen_t *addrlens;
181
182   /**
183    * NULL-terminated array of listen sockets we should take over.
184    */
185   struct GNUNET_NETWORK_Handle **lsocks;
186
187   /**
188    * Task ID of the shutdown task.
189    */
190   struct GNUNET_SCHEDULER_Task *shutdown_task;
191
192   /**
193    * Idle timeout for server.
194    */
195   struct GNUNET_TIME_Relative timeout;
196
197   /**
198    * Overall success/failure of the service start.
199    */
200   int ret;
201
202   /**
203    * If we are daemonizing, this FD is set to the
204    * pipe to the parent.  Send '.' if we started
205    * ok, '!' if not.  -1 if we are not daemonizing.
206    */
207   int ready_confirm_fd;
208
209   /**
210    * Do we close connections if we receive messages
211    * for which we have no handler?
212    */
213   int require_found;
214
215   /**
216    * Do we require a matching UID for UNIX domain socket connections?
217    * #GNUNET_NO means that the UID does not have to match (however,
218    * @e match_gid may still impose other access control checks).
219    */
220   int match_uid;
221
222   /**
223    * Do we require a matching GID for UNIX domain socket connections?
224    * Ignored if @e match_uid is #GNUNET_YES.  Note that this is about
225    * checking that the client's UID is in our group OR that the
226    * client's GID is our GID.  If both "match_gid" and @e match_uid are
227    * #GNUNET_NO, all users on the local system have access.
228    */
229   int match_gid;
230
231   /**
232    * Our options.
233    */
234   enum GNUNET_SERVICE_Options options;
235
236 };
237
238
239 /* ****************** message handlers ****************** */
240
241 /**
242  * Send a 'TEST' message back to the client.
243  *
244  * @param cls the 'struct GNUNET_SERVER_Client' to send TEST to
245  * @param size number of bytes available in 'buf'
246  * @param buf where to copy the message
247  * @return number of bytes written to 'buf'
248  */
249 static size_t
250 write_test (void *cls, size_t size, void *buf)
251 {
252   struct GNUNET_SERVER_Client *client = cls;
253   struct GNUNET_MessageHeader *msg;
254
255   if (size < sizeof (struct GNUNET_MessageHeader))
256   {
257     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
258     return 0;                   /* client disconnected */
259   }
260   msg = (struct GNUNET_MessageHeader *) buf;
261   msg->type = htons (GNUNET_MESSAGE_TYPE_TEST);
262   msg->size = htons (sizeof (struct GNUNET_MessageHeader));
263   GNUNET_SERVER_receive_done (client, GNUNET_OK);
264   return sizeof (struct GNUNET_MessageHeader);
265 }
266
267
268 /**
269  * Handler for TEST message.
270  *
271  * @param cls closure (refers to service)
272  * @param client identification of the client
273  * @param message the actual message
274  */
275 static void
276 handle_test (void *cls, struct GNUNET_SERVER_Client *client,
277              const struct GNUNET_MessageHeader *message)
278 {
279   /* simply bounce message back to acknowledge */
280   if (NULL ==
281       GNUNET_SERVER_notify_transmit_ready (client,
282                                            sizeof (struct GNUNET_MessageHeader),
283                                            GNUNET_TIME_UNIT_FOREVER_REL,
284                                            &write_test, client))
285     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
286 }
287
288
289 /**
290  * Default handlers for all services.  Will be copied and the
291  * "callback_cls" fields will be replaced with the specific service
292  * struct.
293  */
294 static const struct GNUNET_SERVER_MessageHandler defhandlers[] = {
295   {&handle_test, NULL, GNUNET_MESSAGE_TYPE_TEST,
296    sizeof (struct GNUNET_MessageHeader)},
297   {NULL, NULL, 0, 0}
298 };
299
300
301 /* ****************** service core routines ************** */
302
303
304 /**
305  * Check if access to the service is allowed from the given address.
306  *
307  * @param cls closure
308  * @param uc credentials, if available, otherwise NULL
309  * @param addr address
310  * @param addrlen length of address
311  * @return #GNUNET_YES to allow, #GNUNET_NO to deny, #GNUNET_SYSERR
312  *   for unknown address family (will be denied).
313  */
314 static int
315 check_access (void *cls, const struct GNUNET_CONNECTION_Credentials *uc,
316               const struct sockaddr *addr, socklen_t addrlen)
317 {
318   struct GNUNET_SERVICE_Context *sctx = cls;
319   const struct sockaddr_in *i4;
320   const struct sockaddr_in6 *i6;
321   int ret;
322
323   switch (addr->sa_family)
324   {
325   case AF_INET:
326     GNUNET_assert (addrlen == sizeof (struct sockaddr_in));
327     i4 = (const struct sockaddr_in *) addr;
328     ret = ((NULL == sctx->v4_allowed) ||
329            (check_ipv4_listed (sctx->v4_allowed, &i4->sin_addr))) &&
330         ((NULL == sctx->v4_denied) ||
331          (!check_ipv4_listed (sctx->v4_denied, &i4->sin_addr)));
332     break;
333   case AF_INET6:
334     GNUNET_assert (addrlen == sizeof (struct sockaddr_in6));
335     i6 = (const struct sockaddr_in6 *) addr;
336     ret = ((NULL == sctx->v6_allowed) ||
337            (check_ipv6_listed (sctx->v6_allowed, &i6->sin6_addr))) &&
338         ((NULL == sctx->v6_denied) ||
339          (!check_ipv6_listed (sctx->v6_denied, &i6->sin6_addr)));
340     break;
341 #ifndef WINDOWS
342   case AF_UNIX:
343     ret = GNUNET_OK;            /* controlled using file-system ACL now */
344     break;
345 #endif
346   default:
347     LOG (GNUNET_ERROR_TYPE_WARNING, _("Unknown address family %d\n"),
348          addr->sa_family);
349     return GNUNET_SYSERR;
350   }
351   if (GNUNET_OK != ret)
352   {
353     LOG (GNUNET_ERROR_TYPE_WARNING,
354          _("Access from `%s' denied to service `%s'\n"),
355          GNUNET_a2s (addr, addrlen),
356          sctx->service_name);
357   }
358   return ret;
359 }
360
361
362 /**
363  * Get the name of the file where we will
364  * write the PID of the service.
365  *
366  * @param sctx service context
367  * @return name of the file for the process ID
368  */
369 static char *
370 get_pid_file_name (struct GNUNET_SERVICE_Context *sctx)
371 {
372   char *pif;
373
374   if (GNUNET_OK !=
375       GNUNET_CONFIGURATION_get_value_filename (sctx->cfg, sctx->service_name,
376                                                "PIDFILE", &pif))
377     return NULL;
378   return pif;
379 }
380
381
382 /**
383  * Parse an IPv4 access control list.
384  *
385  * @param ret location where to write the ACL (set)
386  * @param sctx service context to use to get the configuration
387  * @param option name of the ACL option to parse
388  * @return #GNUNET_SYSERR on parse error, #GNUNET_OK on success (including
389  *         no ACL configured)
390  */
391 static int
392 process_acl4 (struct GNUNET_STRINGS_IPv4NetworkPolicy **ret,
393               struct GNUNET_SERVICE_Context *sctx,
394               const char *option)
395 {
396   char *opt;
397
398   if (!GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->service_name, option))
399   {
400     *ret = NULL;
401     return GNUNET_OK;
402   }
403   GNUNET_break (GNUNET_OK ==
404                 GNUNET_CONFIGURATION_get_value_string (sctx->cfg,
405                                                        sctx->service_name,
406                                                        option, &opt));
407   if (NULL == (*ret = GNUNET_STRINGS_parse_ipv4_policy (opt)))
408   {
409     LOG (GNUNET_ERROR_TYPE_WARNING,
410          _("Could not parse IPv4 network specification `%s' for `%s:%s'\n"),
411          opt, sctx->service_name, option);
412     GNUNET_free (opt);
413     return GNUNET_SYSERR;
414   }
415   GNUNET_free (opt);
416   return GNUNET_OK;
417 }
418
419
420 /**
421  * Parse an IPv6 access control list.
422  *
423  * @param ret location where to write the ACL (set)
424  * @param sctx service context to use to get the configuration
425  * @param option name of the ACL option to parse
426  * @return #GNUNET_SYSERR on parse error, #GNUNET_OK on success (including
427  *         no ACL configured)
428  */
429 static int
430 process_acl6 (struct GNUNET_STRINGS_IPv6NetworkPolicy **ret,
431               struct GNUNET_SERVICE_Context *sctx,
432               const char *option)
433 {
434   char *opt;
435
436   if (!GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->service_name, option))
437   {
438     *ret = NULL;
439     return GNUNET_OK;
440   }
441   GNUNET_break (GNUNET_OK ==
442                 GNUNET_CONFIGURATION_get_value_string (sctx->cfg,
443                                                        sctx->service_name,
444                                                        option, &opt));
445   if (NULL == (*ret = GNUNET_STRINGS_parse_ipv6_policy (opt)))
446   {
447     LOG (GNUNET_ERROR_TYPE_WARNING,
448          _("Could not parse IPv6 network specification `%s' for `%s:%s'\n"),
449          opt, sctx->service_name, option);
450     GNUNET_free (opt);
451     return GNUNET_SYSERR;
452   }
453   GNUNET_free (opt);
454   return GNUNET_OK;
455 }
456
457
458 /**
459  * Add the given UNIX domain path as an address to the
460  * list (as the first entry).
461  *
462  * @param saddrs array to update
463  * @param saddrlens where to store the address length
464  * @param unixpath path to add
465  * @param abstract #GNUNET_YES to add an abstract UNIX domain socket.  This
466  *          parameter is ignore on systems other than LINUX
467  */
468 static void
469 add_unixpath (struct sockaddr **saddrs,
470               socklen_t *saddrlens,
471               const char *unixpath,
472               int abstract)
473 {
474 #ifdef AF_UNIX
475   struct sockaddr_un *un;
476
477   un = GNUNET_new (struct sockaddr_un);
478   un->sun_family = AF_UNIX;
479   strncpy (un->sun_path, unixpath, sizeof (un->sun_path) - 1);
480 #ifdef LINUX
481   if (GNUNET_YES == abstract)
482     un->sun_path[0] = '\0';
483 #endif
484 #if HAVE_SOCKADDR_IN_SIN_LEN
485   un->sun_len = (u_char) sizeof (struct sockaddr_un);
486 #endif
487   *saddrs = (struct sockaddr *) un;
488   *saddrlens = sizeof (struct sockaddr_un);
489 #else
490   /* this function should never be called
491    * unless AF_UNIX is defined! */
492   GNUNET_assert (0);
493 #endif
494 }
495
496
497 /**
498  * Get the list of addresses that a server for the given service
499  * should bind to.
500  *
501  * @param service_name name of the service
502  * @param cfg configuration (which specifies the addresses)
503  * @param addrs set (call by reference) to an array of pointers to the
504  *              addresses the server should bind to and listen on; the
505  *              array will be NULL-terminated (on success)
506  * @param addr_lens set (call by reference) to an array of the lengths
507  *              of the respective `struct sockaddr` struct in the @a addrs
508  *              array (on success)
509  * @return number of addresses found on success,
510  *              #GNUNET_SYSERR if the configuration
511  *              did not specify reasonable finding information or
512  *              if it specified a hostname that could not be resolved;
513  *              #GNUNET_NO if the number of addresses configured is
514  *              zero (in this case, `*addrs` and `*addr_lens` will be
515  *              set to NULL).
516  */
517 int
518 GNUNET_SERVICE_get_server_addresses (const char *service_name,
519                                      const struct GNUNET_CONFIGURATION_Handle *cfg,
520                                      struct sockaddr ***addrs,
521                                      socklen_t ** addr_lens)
522 {
523   int disablev6;
524   struct GNUNET_NETWORK_Handle *desc;
525   unsigned long long port;
526   char *unixpath;
527   struct addrinfo hints;
528   struct addrinfo *res;
529   struct addrinfo *pos;
530   struct addrinfo *next;
531   unsigned int i;
532   int resi;
533   int ret;
534   int abstract;
535   struct sockaddr **saddrs;
536   socklen_t *saddrlens;
537   char *hostname;
538
539   *addrs = NULL;
540   *addr_lens = NULL;
541   desc = NULL;
542   if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "DISABLEV6"))
543   {
544     if (GNUNET_SYSERR ==
545         (disablev6 =
546          GNUNET_CONFIGURATION_get_value_yesno (cfg, service_name, "DISABLEV6")))
547       return GNUNET_SYSERR;
548   }
549   else
550     disablev6 = GNUNET_NO;
551
552   if (! disablev6)
553   {
554     /* probe IPv6 support */
555     desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0);
556     if (NULL == desc)
557     {
558       if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) ||
559           (EACCES == errno))
560       {
561         LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket");
562         return GNUNET_SYSERR;
563       }
564       LOG (GNUNET_ERROR_TYPE_INFO,
565            _("Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n"),
566            service_name, STRERROR (errno));
567       disablev6 = GNUNET_YES;
568     }
569     else
570     {
571       GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc));
572       desc = NULL;
573     }
574   }
575
576   port = 0;
577   if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "PORT"))
578   {
579     if (GNUNET_OK !=
580         GNUNET_CONFIGURATION_get_value_number (cfg, service_name,
581                                                "PORT", &port))
582     {
583       LOG (GNUNET_ERROR_TYPE_ERROR,
584            _("Require valid port number for service `%s' in configuration!\n"),
585            service_name);
586     }
587     if (port > 65535)
588     {
589       LOG (GNUNET_ERROR_TYPE_ERROR,
590            _("Require valid port number for service `%s' in configuration!\n"),
591            service_name);
592       return GNUNET_SYSERR;
593     }
594   }
595
596   if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "BINDTO"))
597   {
598     GNUNET_break (GNUNET_OK ==
599                   GNUNET_CONFIGURATION_get_value_string (cfg, service_name,
600                                                          "BINDTO", &hostname));
601   }
602   else
603     hostname = NULL;
604
605   unixpath = NULL;
606   abstract = GNUNET_NO;
607 #ifdef AF_UNIX
608   if ((GNUNET_YES ==
609        GNUNET_CONFIGURATION_have_value (cfg, service_name, "UNIXPATH")) &&
610       (GNUNET_OK ==
611        GNUNET_CONFIGURATION_get_value_filename (cfg, service_name, "UNIXPATH",
612                                               &unixpath)) &&
613       (0 < strlen (unixpath)))
614   {
615     /* probe UNIX support */
616     struct sockaddr_un s_un;
617
618     if (strlen (unixpath) >= sizeof (s_un.sun_path))
619     {
620       LOG (GNUNET_ERROR_TYPE_WARNING,
621            _("UNIXPATH `%s' too long, maximum length is %llu\n"), unixpath,
622            (unsigned long long) sizeof (s_un.sun_path));
623       unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath);
624       LOG (GNUNET_ERROR_TYPE_INFO,
625            _("Using `%s' instead\n"),
626            unixpath);
627     }
628 #ifdef LINUX
629     abstract = GNUNET_CONFIGURATION_get_value_yesno (cfg,
630                                                      "TESTING",
631                                                      "USE_ABSTRACT_SOCKETS");
632     if (GNUNET_SYSERR == abstract)
633       abstract = GNUNET_NO;
634 #endif
635     if ((GNUNET_YES != abstract)
636         && (GNUNET_OK !=
637             GNUNET_DISK_directory_create_for_file (unixpath)))
638       GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
639                                 "mkdir",
640                                 unixpath);
641   }
642   if (NULL != unixpath)
643   {
644     desc = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0);
645     if (NULL == desc)
646     {
647       if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) ||
648           (EACCES == errno))
649       {
650         LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket");
651         GNUNET_free_non_null (hostname);
652         GNUNET_free (unixpath);
653         return GNUNET_SYSERR;
654       }
655       LOG (GNUNET_ERROR_TYPE_INFO,
656            _("Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"),
657            service_name,
658            STRERROR (errno));
659       GNUNET_free (unixpath);
660       unixpath = NULL;
661     }
662     else
663     {
664       GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc));
665       desc = NULL;
666     }
667   }
668 #endif
669
670   if ((0 == port) && (NULL == unixpath))
671   {
672     LOG (GNUNET_ERROR_TYPE_ERROR,
673          _("Have neither PORT nor UNIXPATH for service `%s', but one is required\n"),
674          service_name);
675     GNUNET_free_non_null (hostname);
676     return GNUNET_SYSERR;
677   }
678   if (0 == port)
679   {
680     saddrs = GNUNET_malloc (2 * sizeof (struct sockaddr *));
681     saddrlens = GNUNET_malloc (2 * sizeof (socklen_t));
682     add_unixpath (saddrs, saddrlens, unixpath, abstract);
683     GNUNET_free_non_null (unixpath);
684     GNUNET_free_non_null (hostname);
685     *addrs = saddrs;
686     *addr_lens = saddrlens;
687     return 1;
688   }
689
690   if (NULL != hostname)
691   {
692     LOG (GNUNET_ERROR_TYPE_DEBUG,
693          "Resolving `%s' since that is where `%s' will bind to.\n",
694          hostname,
695          service_name);
696     memset (&hints, 0, sizeof (struct addrinfo));
697     if (disablev6)
698       hints.ai_family = AF_INET;
699     hints.ai_protocol = IPPROTO_TCP;
700     if ((0 != (ret = getaddrinfo (hostname, NULL, &hints, &res))) ||
701         (NULL == res))
702     {
703       LOG (GNUNET_ERROR_TYPE_ERROR,
704            _("Failed to resolve `%s': %s\n"),
705            hostname,
706            gai_strerror (ret));
707       GNUNET_free (hostname);
708       GNUNET_free_non_null (unixpath);
709       return GNUNET_SYSERR;
710     }
711     next = res;
712     i = 0;
713     while (NULL != (pos = next))
714     {
715       next = pos->ai_next;
716       if ((disablev6) && (pos->ai_family == AF_INET6))
717         continue;
718       i++;
719     }
720     if (0 == i)
721     {
722       LOG (GNUNET_ERROR_TYPE_ERROR,
723            _("Failed to find %saddress for `%s'.\n"),
724            disablev6 ? "IPv4 " : "",
725            hostname);
726       freeaddrinfo (res);
727       GNUNET_free (hostname);
728       GNUNET_free_non_null (unixpath);
729       return GNUNET_SYSERR;
730     }
731     resi = i;
732     if (NULL != unixpath)
733       resi++;
734     saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *));
735     saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t));
736     i = 0;
737     if (NULL != unixpath)
738     {
739       add_unixpath (saddrs, saddrlens, unixpath, abstract);
740       i++;
741     }
742     next = res;
743     while (NULL != (pos = next))
744     {
745       next = pos->ai_next;
746       if ((disablev6) && (AF_INET6 == pos->ai_family))
747         continue;
748       if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol))
749         continue;               /* not TCP */
750       if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype))
751         continue;               /* huh? */
752       LOG (GNUNET_ERROR_TYPE_DEBUG, "Service `%s' will bind to `%s'\n",
753            service_name, GNUNET_a2s (pos->ai_addr, pos->ai_addrlen));
754       if (AF_INET == pos->ai_family)
755       {
756         GNUNET_assert (sizeof (struct sockaddr_in) == pos->ai_addrlen);
757         saddrlens[i] = pos->ai_addrlen;
758         saddrs[i] = GNUNET_malloc (saddrlens[i]);
759         memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
760         ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
761       }
762       else
763       {
764         GNUNET_assert (AF_INET6 == pos->ai_family);
765         GNUNET_assert (sizeof (struct sockaddr_in6) == pos->ai_addrlen);
766         saddrlens[i] = pos->ai_addrlen;
767         saddrs[i] = GNUNET_malloc (saddrlens[i]);
768         memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
769         ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
770       }
771       i++;
772     }
773     GNUNET_free (hostname);
774     freeaddrinfo (res);
775     resi = i;
776   }
777   else
778   {
779     /* will bind against everything, just set port */
780     if (disablev6)
781     {
782       /* V4-only */
783       resi = 1;
784       if (NULL != unixpath)
785         resi++;
786       i = 0;
787       saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *));
788       saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t));
789       if (NULL != unixpath)
790       {
791         add_unixpath (saddrs, saddrlens, unixpath, abstract);
792         i++;
793       }
794       saddrlens[i] = sizeof (struct sockaddr_in);
795       saddrs[i] = GNUNET_malloc (saddrlens[i]);
796 #if HAVE_SOCKADDR_IN_SIN_LEN
797       ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[i];
798 #endif
799       ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
800       ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
801     }
802     else
803     {
804       /* dual stack */
805       resi = 2;
806       if (NULL != unixpath)
807         resi++;
808       saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *));
809       saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t));
810       i = 0;
811       if (NULL != unixpath)
812       {
813         add_unixpath (saddrs, saddrlens, unixpath, abstract);
814         i++;
815       }
816       saddrlens[i] = sizeof (struct sockaddr_in6);
817       saddrs[i] = GNUNET_malloc (saddrlens[i]);
818 #if HAVE_SOCKADDR_IN_SIN_LEN
819       ((struct sockaddr_in6 *) saddrs[i])->sin6_len = saddrlens[0];
820 #endif
821       ((struct sockaddr_in6 *) saddrs[i])->sin6_family = AF_INET6;
822       ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
823       i++;
824       saddrlens[i] = sizeof (struct sockaddr_in);
825       saddrs[i] = GNUNET_malloc (saddrlens[i]);
826 #if HAVE_SOCKADDR_IN_SIN_LEN
827       ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[1];
828 #endif
829       ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
830       ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
831     }
832   }
833   GNUNET_free_non_null (unixpath);
834   *addrs = saddrs;
835   *addr_lens = saddrlens;
836   return resi;
837 }
838
839
840 #ifdef MINGW
841 /**
842  * Read listen sockets from the parent process (ARM).
843  *
844  * @param sctx service context to initialize
845  * @return #GNUNET_YES if ok, #GNUNET_NO if not ok (must bind yourself),
846  * and #GNUNET_SYSERR on error.
847  */
848 static int
849 receive_sockets_from_parent (struct GNUNET_SERVICE_Context *sctx)
850 {
851   const char *env_buf;
852   int fail;
853   uint64_t count;
854   uint64_t i;
855   HANDLE lsocks_pipe;
856
857   env_buf = getenv ("GNUNET_OS_READ_LSOCKS");
858   if ((NULL == env_buf) || (strlen (env_buf) <= 0))
859     return GNUNET_NO;
860   /* Using W32 API directly here, because this pipe will
861    * never be used outside of this function, and it's just too much of a bother
862    * to create a GNUnet API that boxes a HANDLE (the way it is done with socks)
863    */
864   lsocks_pipe = (HANDLE) strtoul (env_buf, NULL, 10);
865   if ( (0 == lsocks_pipe) || (INVALID_HANDLE_VALUE == lsocks_pipe))
866     return GNUNET_NO;
867   fail = 1;
868   do
869   {
870     int ret;
871     int fail2;
872     DWORD rd;
873
874     ret = ReadFile (lsocks_pipe, &count, sizeof (count), &rd, NULL);
875     if ((0 == ret) || (sizeof (count) != rd) || (0 == count))
876       break;
877     sctx->lsocks =
878         GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (count + 1));
879
880     fail2 = 1;
881     for (i = 0; i < count; i++)
882     {
883       WSAPROTOCOL_INFOA pi;
884       uint64_t size;
885       SOCKET s;
886
887       ret = ReadFile (lsocks_pipe, &size, sizeof (size), &rd, NULL);
888       if ( (0 == ret) || (sizeof (size) != rd) || (sizeof (pi) != size) )
889         break;
890       ret = ReadFile (lsocks_pipe, &pi, sizeof (pi), &rd, NULL);
891       if ( (0 == ret) || (sizeof (pi) != rd))
892         break;
893       s = WSASocketA (pi.iAddressFamily, pi.iSocketType, pi.iProtocol, &pi, 0, WSA_FLAG_OVERLAPPED);
894       sctx->lsocks[i] = GNUNET_NETWORK_socket_box_native (s);
895       if (NULL == sctx->lsocks[i])
896         break;
897       else if (i == count - 1)
898         fail2 = 0;
899     }
900     if (fail2)
901       break;
902     sctx->lsocks[count] = NULL;
903     fail = 0;
904   }
905   while (fail);
906
907   CloseHandle (lsocks_pipe);
908
909   if (fail)
910   {
911     LOG (GNUNET_ERROR_TYPE_ERROR,
912          _("Could not access a pre-bound socket, will try to bind myself\n"));
913     for (i = 0; (i < count) && (NULL != sctx->lsocks[i]); i++)
914       GNUNET_break (0 == GNUNET_NETWORK_socket_close (sctx->lsocks[i]));
915     GNUNET_free_non_null (sctx->lsocks);
916     sctx->lsocks = NULL;
917     return GNUNET_NO;
918   }
919   return GNUNET_YES;
920 }
921 #endif
922
923
924 /**
925  * Setup addr, addrlen, idle_timeout
926  * based on configuration!
927  *
928  * Configuration may specify:
929  * - PORT (where to bind to for TCP)
930  * - UNIXPATH (where to bind to for UNIX domain sockets)
931  * - TIMEOUT (after how many ms does an inactive service timeout);
932  * - DISABLEV6 (disable support for IPv6, otherwise we use dual-stack)
933  * - BINDTO (hostname or IP address to bind to, otherwise we take everything)
934  * - ACCEPT_FROM  (only allow connections from specified IPv4 subnets)
935  * - ACCEPT_FROM6 (only allow connections from specified IPv6 subnets)
936  * - REJECT_FROM  (disallow allow connections from specified IPv4 subnets)
937  * - REJECT_FROM6 (disallow allow connections from specified IPv6 subnets)
938  *
939  * @param sctx service context to initialize
940  * @return #GNUNET_OK if configuration succeeded
941  */
942 static int
943 setup_service (struct GNUNET_SERVICE_Context *sctx)
944 {
945   struct GNUNET_TIME_Relative idleout;
946   int tolerant;
947
948 #ifndef MINGW
949   const char *nfds;
950   unsigned int cnt;
951   int flags;
952 #endif
953
954   if (GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->service_name, "TIMEOUT"))
955   {
956     if (GNUNET_OK !=
957         GNUNET_CONFIGURATION_get_value_time (sctx->cfg, sctx->service_name,
958                                              "TIMEOUT", &idleout))
959     {
960       LOG (GNUNET_ERROR_TYPE_ERROR,
961            _("Specified value for `%s' of service `%s' is invalid\n"),
962            "TIMEOUT", sctx->service_name);
963       return GNUNET_SYSERR;
964     }
965     sctx->timeout = idleout;
966   }
967   else
968     sctx->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
969
970   if (GNUNET_CONFIGURATION_have_value
971       (sctx->cfg, sctx->service_name, "TOLERANT"))
972   {
973     if (GNUNET_SYSERR ==
974         (tolerant =
975          GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, sctx->service_name,
976                                                "TOLERANT")))
977     {
978       LOG (GNUNET_ERROR_TYPE_ERROR,
979            _("Specified value for `%s' of service `%s' is invalid\n"),
980            "TOLERANT", sctx->service_name);
981       return GNUNET_SYSERR;
982     }
983   }
984   else
985     tolerant = GNUNET_NO;
986
987 #ifndef MINGW
988   errno = 0;
989   if ((NULL != (nfds = getenv ("LISTEN_FDS"))) &&
990       (1 == SSCANF (nfds, "%u", &cnt)) && (cnt > 0) && (cnt < FD_SETSIZE) &&
991       (cnt + 4 < FD_SETSIZE))
992   {
993     sctx->lsocks =
994         GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (cnt + 1));
995     while (0 < cnt--)
996     {
997       flags = fcntl (3 + cnt, F_GETFD);
998       if ((flags < 0) || (0 != (flags & FD_CLOEXEC)) ||
999           (NULL ==
1000            (sctx->lsocks[cnt] = GNUNET_NETWORK_socket_box_native (3 + cnt))))
1001       {
1002         LOG (GNUNET_ERROR_TYPE_ERROR,
1003              _
1004              ("Could not access pre-bound socket %u, will try to bind myself\n"),
1005              (unsigned int) 3 + cnt);
1006         cnt++;
1007         while (sctx->lsocks[cnt] != NULL)
1008           GNUNET_break (0 == GNUNET_NETWORK_socket_close (sctx->lsocks[cnt++]));
1009         GNUNET_free (sctx->lsocks);
1010         sctx->lsocks = NULL;
1011         break;
1012       }
1013     }
1014     unsetenv ("LISTEN_FDS");
1015   }
1016 #else
1017   if (getenv ("GNUNET_OS_READ_LSOCKS") != NULL)
1018   {
1019     receive_sockets_from_parent (sctx);
1020     putenv ("GNUNET_OS_READ_LSOCKS=");
1021   }
1022 #endif
1023
1024   if ((NULL == sctx->lsocks) &&
1025       (GNUNET_SYSERR ==
1026        GNUNET_SERVICE_get_server_addresses (sctx->service_name, sctx->cfg,
1027                                             &sctx->addrs, &sctx->addrlens)))
1028     return GNUNET_SYSERR;
1029   sctx->require_found = tolerant ? GNUNET_NO : GNUNET_YES;
1030   sctx->match_uid =
1031       GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, sctx->service_name,
1032                                             "UNIX_MATCH_UID");
1033   sctx->match_gid =
1034       GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, sctx->service_name,
1035                                             "UNIX_MATCH_GID");
1036   process_acl4 (&sctx->v4_denied, sctx, "REJECT_FROM");
1037   process_acl4 (&sctx->v4_allowed, sctx, "ACCEPT_FROM");
1038   process_acl6 (&sctx->v6_denied, sctx, "REJECT_FROM6");
1039   process_acl6 (&sctx->v6_allowed, sctx, "ACCEPT_FROM6");
1040
1041   return GNUNET_OK;
1042 }
1043
1044
1045 /**
1046  * Get the name of the user that'll be used
1047  * to provide the service.
1048  *
1049  * @param sctx service context
1050  * @return value of the 'USERNAME' option
1051  */
1052 static char *
1053 get_user_name (struct GNUNET_SERVICE_Context *sctx)
1054 {
1055   char *un;
1056
1057   if (GNUNET_OK !=
1058       GNUNET_CONFIGURATION_get_value_filename (sctx->cfg, sctx->service_name,
1059                                                "USERNAME", &un))
1060     return NULL;
1061   return un;
1062 }
1063
1064
1065 /**
1066  * Write PID file.
1067  *
1068  * @param sctx service context
1069  * @param pid PID to write (should be equal to 'getpid()'
1070  * @return  #GNUNET_OK on success (including no work to be done)
1071  */
1072 static int
1073 write_pid_file (struct GNUNET_SERVICE_Context *sctx, pid_t pid)
1074 {
1075   FILE *pidfd;
1076   char *pif;
1077   char *user;
1078   char *rdir;
1079   int len;
1080
1081   if (NULL == (pif = get_pid_file_name (sctx)))
1082     return GNUNET_OK;           /* no file desired */
1083   user = get_user_name (sctx);
1084   rdir = GNUNET_strdup (pif);
1085   len = strlen (rdir);
1086   while ((len > 0) && (rdir[len] != DIR_SEPARATOR))
1087     len--;
1088   rdir[len] = '\0';
1089   if (0 != ACCESS (rdir, F_OK))
1090   {
1091     /* we get to create a directory -- and claim it
1092      * as ours! */
1093     (void) GNUNET_DISK_directory_create (rdir);
1094     if ((NULL != user) && (0 < strlen (user)))
1095       GNUNET_DISK_file_change_owner (rdir, user);
1096   }
1097   if (0 != ACCESS (rdir, W_OK | X_OK))
1098   {
1099     LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "access", rdir);
1100     GNUNET_free (rdir);
1101     GNUNET_free_non_null (user);
1102     GNUNET_free (pif);
1103     return GNUNET_SYSERR;
1104   }
1105   GNUNET_free (rdir);
1106   pidfd = FOPEN (pif, "w");
1107   if (NULL == pidfd)
1108   {
1109     LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "fopen", pif);
1110     GNUNET_free (pif);
1111     GNUNET_free_non_null (user);
1112     return GNUNET_SYSERR;
1113   }
1114   if (0 > FPRINTF (pidfd, "%u", pid))
1115     LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fprintf", pif);
1116   GNUNET_break (0 == FCLOSE (pidfd));
1117   if ((NULL != user) && (0 < strlen (user)))
1118     GNUNET_DISK_file_change_owner (pif, user);
1119   GNUNET_free_non_null (user);
1120   GNUNET_free (pif);
1121   return GNUNET_OK;
1122 }
1123
1124
1125 /**
1126  * Task run during shutdown.  Stops the server/service.
1127  *
1128  * @param cls the `struct GNUNET_SERVICE_Context`
1129  */
1130 static void
1131 shutdown_task (void *cls)
1132 {
1133   struct GNUNET_SERVICE_Context *service = cls;
1134   struct GNUNET_SERVER_Handle *server = service->server;
1135
1136   service->shutdown_task = NULL;
1137   if (0 != (service->options & GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN))
1138     GNUNET_SERVER_stop_listening (server);
1139   else
1140     GNUNET_SERVER_destroy (server);
1141 }
1142
1143
1144 /**
1145  * Initial task for the service.
1146  *
1147  * @param cls service context
1148  */
1149 static void
1150 service_task (void *cls)
1151 {
1152   struct GNUNET_SERVICE_Context *sctx = cls;
1153   unsigned int i;
1154
1155   (void) GNUNET_SPEEDUP_start_ (sctx->cfg);
1156   GNUNET_RESOLVER_connect (sctx->cfg);
1157   if (NULL != sctx->lsocks)
1158     sctx->server
1159       = GNUNET_SERVER_create_with_sockets (&check_access, sctx, sctx->lsocks,
1160                                            sctx->timeout, sctx->require_found);
1161   else
1162     sctx->server
1163       = GNUNET_SERVER_create (&check_access, sctx, sctx->addrs, sctx->addrlens,
1164                               sctx->timeout, sctx->require_found);
1165   if (NULL == sctx->server)
1166   {
1167     if (NULL != sctx->addrs)
1168       for (i = 0; NULL != sctx->addrs[i]; i++)
1169         LOG (GNUNET_ERROR_TYPE_INFO,
1170              _("Failed to start `%s' at `%s'\n"),
1171              sctx->service_name, GNUNET_a2s (sctx->addrs[i], sctx->addrlens[i]));
1172     sctx->ret = GNUNET_SYSERR;
1173     return;
1174   }
1175 #ifndef WINDOWS
1176   if (NULL != sctx->addrs)
1177     for (i = 0; NULL != sctx->addrs[i]; i++)
1178       if ((AF_UNIX == sctx->addrs[i]->sa_family)
1179           && ('\0' != ((const struct sockaddr_un *)sctx->addrs[i])->sun_path[0]))
1180         GNUNET_DISK_fix_permissions (((const struct sockaddr_un *)sctx->addrs[i])->sun_path,
1181                                      sctx->match_uid,
1182                                      sctx->match_gid);
1183 #endif
1184
1185
1186   if (0 == (sctx->options & GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN))
1187   {
1188     /* install a task that will kill the server
1189      * process if the scheduler ever gets a shutdown signal */
1190     sctx->shutdown_task = GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
1191                                                          sctx);
1192   }
1193   sctx->my_handlers = GNUNET_malloc (sizeof (defhandlers));
1194   memcpy (sctx->my_handlers, defhandlers, sizeof (defhandlers));
1195   i = 0;
1196   while (NULL != sctx->my_handlers[i].callback)
1197     sctx->my_handlers[i++].callback_cls = sctx;
1198   GNUNET_SERVER_add_handlers (sctx->server, sctx->my_handlers);
1199   if (-1 != sctx->ready_confirm_fd)
1200   {
1201     GNUNET_break (1 == WRITE (sctx->ready_confirm_fd, ".", 1));
1202     GNUNET_break (0 == CLOSE (sctx->ready_confirm_fd));
1203     sctx->ready_confirm_fd = -1;
1204     write_pid_file (sctx, getpid ());
1205   }
1206   if (NULL != sctx->addrs)
1207   {
1208     i = 0;
1209     while (NULL != sctx->addrs[i])
1210     {
1211       LOG (GNUNET_ERROR_TYPE_INFO, _("Service `%s' runs at %s\n"),
1212            sctx->service_name, GNUNET_a2s (sctx->addrs[i], sctx->addrlens[i]));
1213       i++;
1214     }
1215   }
1216   sctx->task (sctx->task_cls, sctx->server, sctx->cfg);
1217 }
1218
1219
1220 /**
1221  * Detach from terminal.
1222  *
1223  * @param sctx service context
1224  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
1225  */
1226 static int
1227 detach_terminal (struct GNUNET_SERVICE_Context *sctx)
1228 {
1229 #ifndef MINGW
1230   pid_t pid;
1231   int nullfd;
1232   int filedes[2];
1233
1234   if (0 != PIPE (filedes))
1235   {
1236     LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "pipe");
1237     return GNUNET_SYSERR;
1238   }
1239   pid = fork ();
1240   if (pid < 0)
1241   {
1242     LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "fork");
1243     return GNUNET_SYSERR;
1244   }
1245   if (0 != pid)
1246   {
1247     /* Parent */
1248     char c;
1249
1250     GNUNET_break (0 == CLOSE (filedes[1]));
1251     c = 'X';
1252     if (1 != READ (filedes[0], &c, sizeof (char)))
1253       LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "read");
1254     fflush (stdout);
1255     switch (c)
1256     {
1257     case '.':
1258       exit (0);
1259     case 'I':
1260       LOG (GNUNET_ERROR_TYPE_INFO, _("Service process failed to initialize\n"));
1261       break;
1262     case 'S':
1263       LOG (GNUNET_ERROR_TYPE_INFO,
1264            _("Service process could not initialize server function\n"));
1265       break;
1266     case 'X':
1267       LOG (GNUNET_ERROR_TYPE_INFO,
1268            _("Service process failed to report status\n"));
1269       break;
1270     }
1271     exit (1);                   /* child reported error */
1272   }
1273   GNUNET_break (0 == CLOSE (0));
1274   GNUNET_break (0 == CLOSE (1));
1275   GNUNET_break (0 == CLOSE (filedes[0]));
1276   nullfd = OPEN ("/dev/null", O_RDWR | O_APPEND);
1277   if (nullfd < 0)
1278     return GNUNET_SYSERR;
1279   /* set stdin/stdout to /dev/null */
1280   if ((dup2 (nullfd, 0) < 0) || (dup2 (nullfd, 1) < 0))
1281   {
1282     LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "dup2");
1283     (void) CLOSE (nullfd);
1284     return GNUNET_SYSERR;
1285   }
1286   (void) CLOSE (nullfd);
1287   /* Detach from controlling terminal */
1288   pid = setsid ();
1289   if (-1 == pid)
1290     LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "setsid");
1291   sctx->ready_confirm_fd = filedes[1];
1292 #else
1293   /* FIXME: we probably need to do something else
1294    * elsewhere in order to fork the process itself... */
1295   FreeConsole ();
1296 #endif
1297   return GNUNET_OK;
1298 }
1299
1300
1301 /**
1302  * Set user ID.
1303  *
1304  * @param sctx service context
1305  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
1306  */
1307 static int
1308 set_user_id (struct GNUNET_SERVICE_Context *sctx)
1309 {
1310   char *user;
1311
1312   if (NULL == (user = get_user_name (sctx)))
1313     return GNUNET_OK;           /* keep */
1314 #ifndef MINGW
1315   struct passwd *pws;
1316
1317   errno = 0;
1318   pws = getpwnam (user);
1319   if (NULL == pws)
1320   {
1321     LOG (GNUNET_ERROR_TYPE_ERROR,
1322          _("Cannot obtain information about user `%s': %s\n"), user,
1323          errno == 0 ? _("No such user") : STRERROR (errno));
1324     GNUNET_free (user);
1325     return GNUNET_SYSERR;
1326   }
1327   if ((0 != setgid (pws->pw_gid)) || (0 != setegid (pws->pw_gid)) ||
1328 #if HAVE_INITGROUPS
1329       (0 != initgroups (user, pws->pw_gid)) ||
1330 #endif
1331       (0 != setuid (pws->pw_uid)) || (0 != seteuid (pws->pw_uid)))
1332   {
1333     if ((0 != setregid (pws->pw_gid, pws->pw_gid)) ||
1334         (0 != setreuid (pws->pw_uid, pws->pw_uid)))
1335     {
1336       LOG (GNUNET_ERROR_TYPE_ERROR, _("Cannot change user/group to `%s': %s\n"),
1337            user, STRERROR (errno));
1338       GNUNET_free (user);
1339       return GNUNET_SYSERR;
1340     }
1341   }
1342 #endif
1343   GNUNET_free (user);
1344   return GNUNET_OK;
1345 }
1346
1347
1348 /**
1349  * Delete the PID file that was created by our parent.
1350  *
1351  * @param sctx service context
1352  */
1353 static void
1354 pid_file_delete (struct GNUNET_SERVICE_Context *sctx)
1355 {
1356   char *pif = get_pid_file_name (sctx);
1357
1358   if (NULL == pif)
1359     return;                     /* no PID file */
1360   if (0 != UNLINK (pif))
1361     LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", pif);
1362   GNUNET_free (pif);
1363 }
1364
1365
1366 /**
1367  * Run a standard GNUnet service startup sequence (initialize loggers
1368  * and configuration, parse options).
1369  *
1370  * @param argc number of command line arguments
1371  * @param argv command line arguments
1372  * @param service_name our service name
1373  * @param options service options
1374  * @param task main task of the service
1375  * @param task_cls closure for @a task
1376  * @return #GNUNET_SYSERR on error, #GNUNET_OK
1377  *         if we shutdown nicely
1378  */
1379 int
1380 GNUNET_SERVICE_run (int argc, char *const *argv,
1381                     const char *service_name,
1382                     enum GNUNET_SERVICE_Options options,
1383                     GNUNET_SERVICE_Main task,
1384                     void *task_cls)
1385 {
1386 #define HANDLE_ERROR do { GNUNET_break (0); goto shutdown; } while (0)
1387
1388   int err;
1389   int ret;
1390   char *cfg_fn;
1391   char *opt_cfg_fn;
1392   char *loglev;
1393   char *logfile;
1394   int do_daemonize;
1395   unsigned int i;
1396   unsigned long long skew_offset;
1397   unsigned long long skew_variance;
1398   long long clock_offset;
1399   struct GNUNET_SERVICE_Context sctx;
1400   struct GNUNET_CONFIGURATION_Handle *cfg;
1401   const char *xdg;
1402
1403   struct GNUNET_GETOPT_CommandLineOption service_options[] = {
1404     GNUNET_GETOPT_OPTION_CFG_FILE (&opt_cfg_fn),
1405     {'d', "daemonize", NULL,
1406      gettext_noop ("do daemonize (detach from terminal)"), 0,
1407      GNUNET_GETOPT_set_one, &do_daemonize},
1408     GNUNET_GETOPT_OPTION_HELP (NULL),
1409     GNUNET_GETOPT_OPTION_LOGLEVEL (&loglev),
1410     GNUNET_GETOPT_OPTION_LOGFILE (&logfile),
1411     GNUNET_GETOPT_OPTION_VERSION (PACKAGE_VERSION " " VCS_VERSION),
1412     GNUNET_GETOPT_OPTION_END
1413   };
1414   err = 1;
1415   do_daemonize = 0;
1416   logfile = NULL;
1417   loglev = NULL;
1418   opt_cfg_fn = NULL;
1419   xdg = getenv ("XDG_CONFIG_HOME");
1420   if (NULL != xdg)
1421     GNUNET_asprintf (&cfg_fn,
1422                      "%s%s%s",
1423                      xdg,
1424                      DIR_SEPARATOR_STR,
1425                      GNUNET_OS_project_data_get ()->config_file);
1426   else
1427     cfg_fn = GNUNET_strdup (GNUNET_OS_project_data_get ()->user_config_file);
1428   memset (&sctx, 0, sizeof (sctx));
1429   sctx.options = options;
1430   sctx.ready_confirm_fd = -1;
1431   sctx.ret = GNUNET_OK;
1432   sctx.timeout = GNUNET_TIME_UNIT_FOREVER_REL;
1433   sctx.task = task;
1434   sctx.task_cls = task_cls;
1435   sctx.service_name = service_name;
1436   sctx.cfg = cfg = GNUNET_CONFIGURATION_create ();
1437
1438   /* setup subsystems */
1439   ret = GNUNET_GETOPT_run (service_name, service_options, argc, argv);
1440   if (GNUNET_SYSERR == ret)
1441     goto shutdown;
1442   if (GNUNET_NO == ret)
1443   {
1444     err = 0;
1445     goto shutdown;
1446   }
1447   if (GNUNET_OK != GNUNET_log_setup (service_name, loglev, logfile))
1448     HANDLE_ERROR;
1449   if (NULL == opt_cfg_fn)
1450     opt_cfg_fn = GNUNET_strdup (cfg_fn);
1451   if (GNUNET_YES == GNUNET_DISK_file_test (opt_cfg_fn))
1452   {
1453     if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, opt_cfg_fn))
1454     {
1455       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1456                   _("Malformed configuration file `%s', exit ...\n"),
1457                   opt_cfg_fn);
1458       goto shutdown;
1459     }
1460   }
1461   else
1462   {
1463     if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, NULL))
1464     {
1465       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1466                   _("Malformed configuration, exit ...\n"));
1467       goto shutdown;
1468     }
1469     if (0 != strcmp (opt_cfg_fn, cfg_fn))
1470       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1471                   _("Could not access configuration file `%s'\n"),
1472                   opt_cfg_fn);
1473   }
1474   if (GNUNET_OK != setup_service (&sctx))
1475     goto shutdown;
1476   if ((1 == do_daemonize) && (GNUNET_OK != detach_terminal (&sctx)))
1477     HANDLE_ERROR;
1478   if (GNUNET_OK != set_user_id (&sctx))
1479     goto shutdown;
1480   LOG (GNUNET_ERROR_TYPE_DEBUG,
1481        "Service `%s' runs with configuration from `%s'\n",
1482        service_name,
1483        opt_cfg_fn);
1484   if ((GNUNET_OK ==
1485        GNUNET_CONFIGURATION_get_value_number (sctx.cfg, "TESTING",
1486                                               "SKEW_OFFSET", &skew_offset)) &&
1487       (GNUNET_OK ==
1488        GNUNET_CONFIGURATION_get_value_number (sctx.cfg, "TESTING",
1489                                               "SKEW_VARIANCE", &skew_variance)))
1490   {
1491     clock_offset = skew_offset - skew_variance;
1492     GNUNET_TIME_set_offset (clock_offset);
1493     LOG (GNUNET_ERROR_TYPE_DEBUG, "Skewing clock by %dll ms\n", clock_offset);
1494   }
1495   /* actually run service */
1496   err = 0;
1497   GNUNET_SCHEDULER_run (&service_task, &sctx);
1498   /* shutdown */
1499   if ((1 == do_daemonize) && (NULL != sctx.server))
1500     pid_file_delete (&sctx);
1501   GNUNET_free_non_null (sctx.my_handlers);
1502
1503 shutdown:
1504   if (-1 != sctx.ready_confirm_fd)
1505   {
1506     if (1 != WRITE (sctx.ready_confirm_fd, err ? "I" : "S", 1))
1507       LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "write");
1508     GNUNET_break (0 == CLOSE (sctx.ready_confirm_fd));
1509   }
1510 #if HAVE_MALLINFO
1511   {
1512     char *counter;
1513
1514     if ( (GNUNET_YES ==
1515           GNUNET_CONFIGURATION_have_value (sctx.cfg, service_name,
1516                                            "GAUGER_HEAP")) &&
1517          (GNUNET_OK ==
1518           GNUNET_CONFIGURATION_get_value_string (sctx.cfg, service_name,
1519                                                  "GAUGER_HEAP",
1520                                                  &counter)) )
1521     {
1522       struct mallinfo mi;
1523
1524       mi = mallinfo ();
1525       GAUGER (service_name, counter, mi.usmblks, "blocks");
1526       GNUNET_free (counter);
1527     }
1528   }
1529 #endif
1530   GNUNET_SPEEDUP_stop_ ();
1531   GNUNET_CONFIGURATION_destroy (cfg);
1532   i = 0;
1533   if (NULL != sctx.addrs)
1534     while (NULL != sctx.addrs[i])
1535       GNUNET_free (sctx.addrs[i++]);
1536   GNUNET_free_non_null (sctx.addrs);
1537   GNUNET_free_non_null (sctx.addrlens);
1538   GNUNET_free_non_null (logfile);
1539   GNUNET_free_non_null (loglev);
1540   GNUNET_free (cfg_fn);
1541   GNUNET_free_non_null (opt_cfg_fn);
1542   GNUNET_free_non_null (sctx.v4_denied);
1543   GNUNET_free_non_null (sctx.v6_denied);
1544   GNUNET_free_non_null (sctx.v4_allowed);
1545   GNUNET_free_non_null (sctx.v6_allowed);
1546
1547   return err ? GNUNET_SYSERR : sctx.ret;
1548 }
1549
1550
1551 /**
1552  * Run a service startup sequence within an existing
1553  * initialized system.
1554  *
1555  * @param service_name our service name
1556  * @param cfg configuration to use
1557  * @param options service options
1558  * @return NULL on error, service handle
1559  */
1560 struct GNUNET_SERVICE_Context *
1561 GNUNET_SERVICE_start (const char *service_name,
1562                       const struct GNUNET_CONFIGURATION_Handle *cfg,
1563                       enum GNUNET_SERVICE_Options options)
1564 {
1565   int i;
1566   struct GNUNET_SERVICE_Context *sctx;
1567
1568   sctx = GNUNET_new (struct GNUNET_SERVICE_Context);
1569   sctx->ready_confirm_fd = -1;  /* no daemonizing */
1570   sctx->ret = GNUNET_OK;
1571   sctx->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
1572   sctx->service_name = service_name;
1573   sctx->cfg = cfg;
1574   sctx->options = options;
1575
1576   /* setup subsystems */
1577   if (GNUNET_OK != setup_service (sctx))
1578   {
1579     GNUNET_SERVICE_stop (sctx);
1580     return NULL;
1581   }
1582   if (NULL != sctx->lsocks)
1583     sctx->server =
1584         GNUNET_SERVER_create_with_sockets (&check_access, sctx, sctx->lsocks,
1585                                            sctx->timeout, sctx->require_found);
1586   else
1587     sctx->server =
1588         GNUNET_SERVER_create (&check_access, sctx, sctx->addrs, sctx->addrlens,
1589                               sctx->timeout, sctx->require_found);
1590
1591   if (NULL == sctx->server)
1592   {
1593     GNUNET_SERVICE_stop (sctx);
1594     return NULL;
1595   }
1596 #ifndef WINDOWS
1597   if (NULL != sctx->addrs)
1598     for (i = 0; NULL != sctx->addrs[i]; i++)
1599       if ((AF_UNIX == sctx->addrs[i]->sa_family)
1600           && ('\0' != ((const struct sockaddr_un *)sctx->addrs[i])->sun_path[0]))
1601         GNUNET_DISK_fix_permissions (((const struct sockaddr_un *)sctx->addrs[i])->sun_path,
1602                                      sctx->match_uid,
1603                                      sctx->match_gid);
1604 #endif
1605   sctx->my_handlers = GNUNET_malloc (sizeof (defhandlers));
1606   memcpy (sctx->my_handlers, defhandlers, sizeof (defhandlers));
1607   i = 0;
1608   while ((sctx->my_handlers[i].callback != NULL))
1609     sctx->my_handlers[i++].callback_cls = sctx;
1610   GNUNET_SERVER_add_handlers (sctx->server, sctx->my_handlers);
1611   return sctx;
1612 }
1613
1614
1615 /**
1616  * Obtain the server used by a service.  Note that the server must NOT
1617  * be destroyed by the caller.
1618  *
1619  * @param ctx the service context returned from the start function
1620  * @return handle to the server for this service, NULL if there is none
1621  */
1622 struct GNUNET_SERVER_Handle *
1623 GNUNET_SERVICE_get_server (struct GNUNET_SERVICE_Context *ctx)
1624 {
1625   return ctx->server;
1626 }
1627
1628
1629 /**
1630  * Get the NULL-terminated array of listen sockets for this service.
1631  *
1632  * @param ctx service context to query
1633  * @return NULL if there are no listen sockets, otherwise NULL-terminated
1634  *              array of listen sockets.
1635  */
1636 struct GNUNET_NETWORK_Handle *const*
1637 GNUNET_SERVICE_get_listen_sockets (struct GNUNET_SERVICE_Context *ctx)
1638 {
1639   return ctx->lsocks;
1640 }
1641
1642
1643 /**
1644  * Stop a service that was started with "GNUNET_SERVICE_start".
1645  *
1646  * @param sctx the service context returned from the start function
1647  */
1648 void
1649 GNUNET_SERVICE_stop (struct GNUNET_SERVICE_Context *sctx)
1650 {
1651   unsigned int i;
1652
1653 #if HAVE_MALLINFO
1654   {
1655     char *counter;
1656
1657     if ( (GNUNET_YES ==
1658           GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->service_name,
1659                                            "GAUGER_HEAP")) &&
1660          (GNUNET_OK ==
1661           GNUNET_CONFIGURATION_get_value_string (sctx->cfg, sctx->service_name,
1662                                                  "GAUGER_HEAP",
1663                                                  &counter)) )
1664     {
1665       struct mallinfo mi;
1666
1667       mi = mallinfo ();
1668       GAUGER (sctx->service_name, counter, mi.usmblks, "blocks");
1669       GNUNET_free (counter);
1670     }
1671   }
1672 #endif
1673   if (NULL != sctx->shutdown_task)
1674   {
1675     GNUNET_SCHEDULER_cancel (sctx->shutdown_task);
1676     sctx->shutdown_task = NULL;
1677   }
1678   if (NULL != sctx->server)
1679     GNUNET_SERVER_destroy (sctx->server);
1680   GNUNET_free_non_null (sctx->my_handlers);
1681   if (NULL != sctx->addrs)
1682   {
1683     i = 0;
1684     while (NULL != sctx->addrs[i])
1685       GNUNET_free (sctx->addrs[i++]);
1686     GNUNET_free (sctx->addrs);
1687   }
1688   GNUNET_free_non_null (sctx->addrlens);
1689   GNUNET_free_non_null (sctx->v4_denied);
1690   GNUNET_free_non_null (sctx->v6_denied);
1691   GNUNET_free_non_null (sctx->v4_allowed);
1692   GNUNET_free_non_null (sctx->v6_allowed);
1693   GNUNET_free (sctx);
1694 }
1695
1696
1697 /* end of service.c */