uncrustify as demanded.
[oweals/gnunet.git] / src / util / service.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2016 GNUnet e.V.
4
5      GNUnet is free software: you can redistribute it and/or modify it
6      under the terms of the GNU Affero General Public License as published
7      by the Free Software Foundation, either version 3 of the License,
8      or (at your 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      Affero General Public License for more details.
14
15      You should have received a copy of the GNU Affero General Public License
16      along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18      SPDX-License-Identifier: AGPL3.0-or-later
19  */
20
21 /**
22  * @file util/service.c
23  * @brief functions related to starting services (redesign)
24  * @author Christian Grothoff
25  * @author Florian Dold
26  */
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
29 #include "gnunet_protocols.h"
30 #include "gnunet_constants.h"
31 #include "gnunet_resolver_service.h"
32 #include "speedup.h"
33
34 #if HAVE_MALLINFO
35 #include <malloc.h>
36 #include "gauger.h"
37 #endif
38
39
40 #define LOG(kind, ...) GNUNET_log_from(kind, "util-service", __VA_ARGS__)
41
42 #define LOG_STRERROR(kind, syscall) \
43   GNUNET_log_from_strerror(kind, "util-service", syscall)
44
45 #define LOG_STRERROR_FILE(kind, syscall, filename) \
46   GNUNET_log_from_strerror_file(kind, "util-service", syscall, filename)
47
48
49 /**
50  * Information the service tracks per listen operation.
51  */
52 struct ServiceListenContext {
53   /**
54    * Kept in a DLL.
55    */
56   struct ServiceListenContext *next;
57
58   /**
59    * Kept in a DLL.
60    */
61   struct ServiceListenContext *prev;
62
63   /**
64    * Service this listen context belongs to.
65    */
66   struct GNUNET_SERVICE_Handle *sh;
67
68   /**
69    * Socket we are listening on.
70    */
71   struct GNUNET_NETWORK_Handle *listen_socket;
72
73   /**
74    * Task scheduled to do the listening.
75    */
76   struct GNUNET_SCHEDULER_Task *listen_task;
77 };
78
79
80 /**
81  * Reasons why we might be suspended.
82  */
83 enum SuspendReason {
84   /**
85    * We are running normally.
86    */
87   SUSPEND_STATE_NONE = 0,
88
89   /**
90    * Application requested it.
91    */
92   SUSPEND_STATE_APP = 1,
93
94   /**
95    * OS ran out of file descriptors.
96    */
97   SUSPEND_STATE_EMFILE = 2,
98
99   /**
100    * Both reasons, APP and EMFILE apply.
101    */
102   SUSPEND_STATE_APP_AND_EMFILE = 3,
103
104   /**
105    * Suspension because service was permanently shutdown.
106    */
107   SUSPEND_STATE_SHUTDOWN = 4
108 };
109
110
111 /**
112  * Handle to a service.
113  */
114 struct GNUNET_SERVICE_Handle {
115   /**
116    * Our configuration.
117    */
118   const struct GNUNET_CONFIGURATION_Handle *cfg;
119
120   /**
121    * Name of our service.
122    */
123   const char *service_name;
124
125   /**
126    * Main service-specific task to run.
127    */
128   GNUNET_SERVICE_InitCallback service_init_cb;
129
130   /**
131    * Function to call when clients connect.
132    */
133   GNUNET_SERVICE_ConnectHandler connect_cb;
134
135   /**
136    * Function to call when clients disconnect / are disconnected.
137    */
138   GNUNET_SERVICE_DisconnectHandler disconnect_cb;
139
140   /**
141    * Closure for @e service_init_cb, @e connect_cb, @e disconnect_cb.
142    */
143   void *cb_cls;
144
145   /**
146    * DLL of listen sockets used to accept new connections.
147    */
148   struct ServiceListenContext *slc_head;
149
150   /**
151    * DLL of listen sockets used to accept new connections.
152    */
153   struct ServiceListenContext *slc_tail;
154
155   /**
156    * Our clients, kept in a DLL.
157    */
158   struct GNUNET_SERVICE_Client *clients_head;
159
160   /**
161    * Our clients, kept in a DLL.
162    */
163   struct GNUNET_SERVICE_Client *clients_tail;
164
165   /**
166    * Message handlers to use for all clients.
167    */
168   struct GNUNET_MQ_MessageHandler *handlers;
169
170   /**
171    * Closure for @e task.
172    */
173   void *task_cls;
174
175   /**
176    * IPv4 addresses that are not allowed to connect.
177    */
178   struct GNUNET_STRINGS_IPv4NetworkPolicy *v4_denied;
179
180   /**
181    * IPv6 addresses that are not allowed to connect.
182    */
183   struct GNUNET_STRINGS_IPv6NetworkPolicy *v6_denied;
184
185   /**
186    * IPv4 addresses that are allowed to connect (if not
187    * set, all are allowed).
188    */
189   struct GNUNET_STRINGS_IPv4NetworkPolicy *v4_allowed;
190
191   /**
192    * IPv6 addresses that are allowed to connect (if not
193    * set, all are allowed).
194    */
195   struct GNUNET_STRINGS_IPv6NetworkPolicy *v6_allowed;
196
197   /**
198    * Do we require a matching UID for UNIX domain socket connections?
199    * #GNUNET_NO means that the UID does not have to match (however,
200    * @e match_gid may still impose other access control checks).
201    */
202   int match_uid;
203
204   /**
205    * Do we require a matching GID for UNIX domain socket connections?
206    * Ignored if @e match_uid is #GNUNET_YES.  Note that this is about
207    * checking that the client's UID is in our group OR that the
208    * client's GID is our GID.  If both "match_gid" and @e match_uid are
209    * #GNUNET_NO, all users on the local system have access.
210    */
211   int match_gid;
212
213   /**
214    * Are we suspended, and if so, why?
215    */
216   enum SuspendReason suspend_state;
217
218   /**
219    * Our options.
220    */
221   enum GNUNET_SERVICE_Options options;
222
223   /**
224    * If we are daemonizing, this FD is set to the
225    * pipe to the parent.  Send '.' if we started
226    * ok, '!' if not.  -1 if we are not daemonizing.
227    */
228   int ready_confirm_fd;
229
230   /**
231    * Overall success/failure of the service start.
232    */
233   int ret;
234
235   /**
236    * If #GNUNET_YES, consider unknown message types an error where the
237    * client is disconnected.
238    */
239   int require_found;
240 };
241
242
243 /**
244  * Handle to a client that is connected to a service.
245  */
246 struct GNUNET_SERVICE_Client {
247   /**
248    * Kept in a DLL.
249    */
250   struct GNUNET_SERVICE_Client *next;
251
252   /**
253    * Kept in a DLL.
254    */
255   struct GNUNET_SERVICE_Client *prev;
256
257   /**
258    * Service that this client belongs to.
259    */
260   struct GNUNET_SERVICE_Handle *sh;
261
262   /**
263    * Socket of this client.
264    */
265   struct GNUNET_NETWORK_Handle *sock;
266
267   /**
268    * Message queue for the client.
269    */
270   struct GNUNET_MQ_Handle *mq;
271
272   /**
273    * Tokenizer we use for processing incoming data.
274    */
275   struct GNUNET_MessageStreamTokenizer *mst;
276
277   /**
278    * Task that warns about missing calls to
279    * #GNUNET_SERVICE_client_continue().
280    */
281   struct GNUNET_SCHEDULER_Task *warn_task;
282
283   /**
284    * Task run to finish dropping the client after the stack has
285    * properly unwound.
286    */
287   struct GNUNET_SCHEDULER_Task *drop_task;
288
289   /**
290    * Task that receives data from the client to
291    * pass it to the handlers.
292    */
293   struct GNUNET_SCHEDULER_Task *recv_task;
294
295   /**
296    * Task that transmit data to the client.
297    */
298   struct GNUNET_SCHEDULER_Task *send_task;
299
300   /**
301    * Pointer to the message to be transmitted by @e send_task.
302    */
303   const struct GNUNET_MessageHeader *msg;
304
305   /**
306    * User context value, value returned from
307    * the connect callback.
308    */
309   void *user_context;
310
311   /**
312    * Time when we last gave a message from this client
313    * to the application.
314    */
315   struct GNUNET_TIME_Absolute warn_start;
316
317   /**
318    * Current position in @e msg at which we are transmitting.
319    */
320   size_t msg_pos;
321
322   /**
323    * Persist the file handle for this client no matter what happens,
324    * force the OS to close once the process actually dies.  Should only
325    * be used in special cases!
326    */
327   int persist;
328
329   /**
330    * Is this client a 'monitor' client that should not be counted
331    * when deciding on destroying the server during soft shutdown?
332    * (see also #GNUNET_SERVICE_start)
333    */
334   int is_monitor;
335
336   /**
337    * Are we waiting for the application to call #GNUNET_SERVICE_client_continue()?
338    */
339   int needs_continue;
340
341   /**
342    * Type of last message processed (for warn_no_receive_done).
343    */
344   uint16_t warn_type;
345 };
346
347
348 /**
349  * Check if any of the clients we have left are unrelated to
350  * monitoring.
351  *
352  * @param sh service to check clients for
353  * @return #GNUNET_YES if we have non-monitoring clients left
354  */
355 static int
356 have_non_monitor_clients(struct GNUNET_SERVICE_Handle *sh)
357 {
358   for (struct GNUNET_SERVICE_Client *client = sh->clients_head; NULL != client;
359        client = client->next)
360     {
361       if (client->is_monitor)
362         continue;
363       return GNUNET_YES;
364     }
365   return GNUNET_NO;
366 }
367
368
369 /**
370  * Suspend accepting connections from the listen socket temporarily.
371  * Resume activity using #do_resume.
372  *
373  * @param sh service to stop accepting connections.
374  * @param sr reason for suspending accepting connections
375  */
376 static void
377 do_suspend(struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr)
378 {
379   struct ServiceListenContext *slc;
380
381   GNUNET_assert(0 == (sh->suspend_state & sr));
382   sh->suspend_state |= sr;
383   for (slc = sh->slc_head; NULL != slc; slc = slc->next)
384     {
385       if (NULL != slc->listen_task)
386         {
387           GNUNET_SCHEDULER_cancel(slc->listen_task);
388           slc->listen_task = NULL;
389         }
390     }
391 }
392
393
394 /**
395  * Shutdown task triggered when a service should be terminated.
396  * This considers active clients and the service options to see
397  * how this specific service is to be terminated, and depending
398  * on this proceeds with the shutdown logic.
399  *
400  * @param cls our `struct GNUNET_SERVICE_Handle`
401  */
402 static void
403 service_shutdown(void *cls)
404 {
405   struct GNUNET_SERVICE_Handle *sh = cls;
406
407   switch (sh->options)
408     {
409     case GNUNET_SERVICE_OPTION_NONE:
410       GNUNET_SERVICE_shutdown(sh);
411       break;
412
413     case GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN:
414       /* This task should never be run if we are using
415          the manual shutdown. */
416       GNUNET_assert(0);
417       break;
418
419     case GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN:
420       if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN))
421         do_suspend(sh, SUSPEND_STATE_SHUTDOWN);
422       if (GNUNET_NO == have_non_monitor_clients(sh))
423         GNUNET_SERVICE_shutdown(sh);
424       break;
425     }
426 }
427
428
429 /**
430  * Check if the given IP address is in the list of IP addresses.
431  *
432  * @param list a list of networks
433  * @param add the IP to check (in network byte order)
434  * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is
435  */
436 static int
437 check_ipv4_listed(const struct GNUNET_STRINGS_IPv4NetworkPolicy *list,
438                   const struct in_addr *add)
439 {
440   unsigned int i;
441
442   if (NULL == list)
443     return GNUNET_NO;
444   i = 0;
445   while ((0 != list[i].network.s_addr) || (0 != list[i].netmask.s_addr))
446     {
447       if ((add->s_addr & list[i].netmask.s_addr) ==
448           (list[i].network.s_addr & list[i].netmask.s_addr))
449         return GNUNET_YES;
450       i++;
451     }
452   return GNUNET_NO;
453 }
454
455
456 /**
457  * Check if the given IP address is in the list of IP addresses.
458  *
459  * @param list a list of networks
460  * @param ip the IP to check (in network byte order)
461  * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is
462  */
463 static int
464 check_ipv6_listed(const struct GNUNET_STRINGS_IPv6NetworkPolicy *list,
465                   const struct in6_addr *ip)
466 {
467   unsigned int i;
468   unsigned int j;
469
470   if (NULL == list)
471     return GNUNET_NO;
472   i = 0;
473 NEXT:
474   while (0 != GNUNET_is_zero(&list[i].network))
475     {
476       for (j = 0; j < sizeof(struct in6_addr) / sizeof(int); j++)
477         if (((((int *)ip)[j] & ((int *)&list[i].netmask)[j])) !=
478             (((int *)&list[i].network)[j] & ((int *)&list[i].netmask)[j]))
479           {
480             i++;
481             goto NEXT;
482           }
483       return GNUNET_YES;
484     }
485   return GNUNET_NO;
486 }
487
488
489 /**
490  * Task run when we are ready to transmit data to the
491  * client.
492  *
493  * @param cls the `struct GNUNET_SERVICE_Client *` to send to
494  */
495 static void
496 do_send(void *cls)
497 {
498   struct GNUNET_SERVICE_Client *client = cls;
499   ssize_t ret;
500   size_t left;
501   const char *buf;
502
503   LOG(GNUNET_ERROR_TYPE_DEBUG,
504       "service: sending message with type %u\n",
505       ntohs(client->msg->type));
506
507
508   client->send_task = NULL;
509   buf = (const char *)client->msg;
510   left = ntohs(client->msg->size) - client->msg_pos;
511   ret = GNUNET_NETWORK_socket_send(client->sock, &buf[client->msg_pos], left);
512   GNUNET_assert(ret <= (ssize_t)left);
513   if (0 == ret)
514     {
515       LOG(GNUNET_ERROR_TYPE_DEBUG, "no data send");
516       GNUNET_MQ_inject_error(client->mq, GNUNET_MQ_ERROR_WRITE);
517       return;
518     }
519   if (-1 == ret)
520     {
521       if ((EAGAIN == errno) || (EINTR == errno))
522         {
523           /* ignore */
524           ret = 0;
525         }
526       else
527         {
528           if (EPIPE != errno)
529             GNUNET_log_strerror(GNUNET_ERROR_TYPE_WARNING, "send");
530           LOG(GNUNET_ERROR_TYPE_DEBUG,
531               "socket send returned with error code %i",
532               errno);
533           GNUNET_MQ_inject_error(client->mq, GNUNET_MQ_ERROR_WRITE);
534           return;
535         }
536     }
537   if (0 == client->msg_pos)
538     {
539       GNUNET_MQ_impl_send_in_flight(client->mq);
540     }
541   client->msg_pos += ret;
542   if (left > (size_t)ret)
543     {
544       GNUNET_assert(NULL == client->drop_task);
545       client->send_task =
546         GNUNET_SCHEDULER_add_write_net(GNUNET_TIME_UNIT_FOREVER_REL,
547                                        client->sock,
548                                        &do_send,
549                                        client);
550       return;
551     }
552   GNUNET_MQ_impl_send_continue(client->mq);
553 }
554
555
556 /**
557  * Signature of functions implementing the sending functionality of a
558  * message queue.
559  *
560  * @param mq the message queue
561  * @param msg the message to send
562  * @param impl_state our `struct GNUNET_SERVICE_Client *`
563  */
564 static void
565 service_mq_send(struct GNUNET_MQ_Handle *mq,
566                 const struct GNUNET_MessageHeader *msg,
567                 void *impl_state)
568 {
569   struct GNUNET_SERVICE_Client *client = impl_state;
570
571   (void)mq;
572   if (NULL != client->drop_task)
573     return; /* we're going down right now, do not try to send */
574   GNUNET_assert(NULL == client->send_task);
575   LOG(GNUNET_ERROR_TYPE_DEBUG,
576       "Sending message of type %u and size %u to client\n",
577       ntohs(msg->type),
578       ntohs(msg->size));
579   client->msg = msg;
580   client->msg_pos = 0;
581   client->send_task =
582     GNUNET_SCHEDULER_add_write_net(GNUNET_TIME_UNIT_FOREVER_REL,
583                                    client->sock,
584                                    &do_send,
585                                    client);
586 }
587
588
589 /**
590  * Implementation function that cancels the currently sent message.
591  *
592  * @param mq message queue
593  * @param impl_state state specific to the implementation
594  */
595 static void
596 service_mq_cancel(struct GNUNET_MQ_Handle *mq, void *impl_state)
597 {
598   struct GNUNET_SERVICE_Client *client = impl_state;
599
600   (void)mq;
601   GNUNET_assert(0 == client->msg_pos);
602   client->msg = NULL;
603   GNUNET_SCHEDULER_cancel(client->send_task);
604   client->send_task = NULL;
605 }
606
607
608 /**
609  * Generic error handler, called with the appropriate
610  * error code and the same closure specified at the creation of
611  * the message queue.
612  * Not every message queue implementation supports an error handler.
613  *
614  * @param cls closure with our `struct GNUNET_SERVICE_Client`
615  * @param error error code
616  */
617 static void
618 service_mq_error_handler(void *cls, enum GNUNET_MQ_Error error)
619 {
620   struct GNUNET_SERVICE_Client *client = cls;
621   struct GNUNET_SERVICE_Handle *sh = client->sh;
622
623   if ((GNUNET_MQ_ERROR_NO_MATCH == error) && (GNUNET_NO == sh->require_found))
624     {
625       GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
626                  "No handler for message of type %u found\n",
627                  (unsigned int)client->warn_type);
628       GNUNET_SERVICE_client_continue(client);
629       return; /* ignore error */
630     }
631   GNUNET_SERVICE_client_drop(client);
632 }
633
634
635 /**
636  * Task run to warn about missing calls to #GNUNET_SERVICE_client_continue().
637  *
638  * @param cls our `struct GNUNET_SERVICE_Client *` to process more requests from
639  */
640 static void
641 warn_no_client_continue(void *cls)
642 {
643   struct GNUNET_SERVICE_Client *client = cls;
644
645   GNUNET_break(
646     0 !=
647     client->warn_type); /* type should never be 0 here, as we don't use 0 */
648   client->warn_task = GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_UNIT_MINUTES,
649                                                    &warn_no_client_continue,
650                                                    client);
651   LOG(
652     GNUNET_ERROR_TYPE_WARNING,
653     _(
654       "Processing code for message of type %u did not call `GNUNET_SERVICE_client_continue' after %s\n"),
655     (unsigned int)client->warn_type,
656     GNUNET_STRINGS_relative_time_to_string(GNUNET_TIME_absolute_get_duration(
657                                              client->warn_start),
658                                            GNUNET_YES));
659 }
660
661
662 /**
663  * Functions with this signature are called whenever a
664  * complete message is received by the tokenizer for a client.
665  *
666  * Do not call #GNUNET_MST_destroy() from within
667  * the scope of this callback.
668  *
669  * @param cls closure with the `struct GNUNET_SERVICE_Client *`
670  * @param message the actual message
671  * @return #GNUNET_OK on success, #GNUNET_SYSERR if the client was dropped
672  */
673 static int
674 service_client_mst_cb(void *cls, const struct GNUNET_MessageHeader *message)
675 {
676   struct GNUNET_SERVICE_Client *client = cls;
677
678   LOG(GNUNET_ERROR_TYPE_DEBUG,
679       "Received message of type %u and size %u from client\n",
680       ntohs(message->type),
681       ntohs(message->size));
682   GNUNET_assert(GNUNET_NO == client->needs_continue);
683   client->needs_continue = GNUNET_YES;
684   client->warn_type = ntohs(message->type);
685   client->warn_start = GNUNET_TIME_absolute_get();
686   GNUNET_assert(NULL == client->warn_task);
687   client->warn_task = GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_UNIT_MINUTES,
688                                                    &warn_no_client_continue,
689                                                    client);
690   GNUNET_MQ_inject_message(client->mq, message);
691   if (NULL != client->drop_task)
692     return GNUNET_SYSERR;
693   return GNUNET_OK;
694 }
695
696
697 /**
698  * A client sent us data. Receive and process it.  If we are done,
699  * reschedule this task.
700  *
701  * @param cls the `struct GNUNET_SERVICE_Client` that sent us data.
702  */
703 static void
704 service_client_recv(void *cls)
705 {
706   struct GNUNET_SERVICE_Client *client = cls;
707   int ret;
708
709   client->recv_task = NULL;
710   ret = GNUNET_MST_read(client->mst, client->sock, GNUNET_NO, GNUNET_YES);
711   if (GNUNET_SYSERR == ret)
712     {
713       /* client closed connection (or IO error) */
714       if (NULL == client->drop_task)
715         {
716           GNUNET_assert(GNUNET_NO == client->needs_continue);
717           GNUNET_SERVICE_client_drop(client);
718         }
719       return;
720     }
721   if (GNUNET_NO == ret)
722     return; /* more messages in buffer, wait for application
723                to be done processing */
724   GNUNET_assert(GNUNET_OK == ret);
725   if (GNUNET_YES == client->needs_continue)
726     return;
727   if (NULL != client->recv_task)
728     return;
729   /* MST needs more data, re-schedule read job */
730   client->recv_task =
731     GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL,
732                                   client->sock,
733                                   &service_client_recv,
734                                   client);
735 }
736
737
738 /**
739  * We have successfully accepted a connection from a client.  Now
740  * setup the client (with the scheduler) and tell the application.
741  *
742  * @param sh service that accepted the client
743  * @param sock socket associated with the client
744  */
745 static void
746 start_client(struct GNUNET_SERVICE_Handle *sh,
747              struct GNUNET_NETWORK_Handle *csock)
748 {
749   struct GNUNET_SERVICE_Client *client;
750
751   client = GNUNET_new(struct GNUNET_SERVICE_Client);
752   GNUNET_CONTAINER_DLL_insert(sh->clients_head, sh->clients_tail, client);
753   client->sh = sh;
754   client->sock = csock;
755   client->mq = GNUNET_MQ_queue_for_callbacks(&service_mq_send,
756                                              NULL,
757                                              &service_mq_cancel,
758                                              client,
759                                              sh->handlers,
760                                              &service_mq_error_handler,
761                                              client);
762   client->mst = GNUNET_MST_create(&service_client_mst_cb, client);
763   if (NULL != sh->connect_cb)
764     client->user_context = sh->connect_cb(sh->cb_cls, client, client->mq);
765   GNUNET_MQ_set_handlers_closure(client->mq, client->user_context);
766   client->recv_task =
767     GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL,
768                                   client->sock,
769                                   &service_client_recv,
770                                   client);
771 }
772
773
774 /**
775  * We have a client. Accept the incoming socket(s) (and reschedule
776  * the listen task).
777  *
778  * @param cls the `struct ServiceListenContext` of the ready listen socket
779  */
780 static void
781 accept_client(void *cls)
782 {
783   struct ServiceListenContext *slc = cls;
784   struct GNUNET_SERVICE_Handle *sh = slc->sh;
785
786   slc->listen_task = NULL;
787   while (1)
788     {
789       struct GNUNET_NETWORK_Handle *sock;
790       const struct sockaddr_in *v4;
791       const struct sockaddr_in6 *v6;
792       struct sockaddr_storage sa;
793       socklen_t addrlen;
794       int ok;
795
796       addrlen = sizeof(sa);
797       sock = GNUNET_NETWORK_socket_accept(slc->listen_socket,
798                                           (struct sockaddr *)&sa,
799                                           &addrlen);
800       if (NULL == sock)
801         {
802           if (EMFILE == errno)
803             do_suspend(sh, SUSPEND_STATE_EMFILE);
804           else if (EAGAIN != errno)
805             GNUNET_log_strerror(GNUNET_ERROR_TYPE_WARNING, "accept");
806           break;
807         }
808       switch (sa.ss_family)
809         {
810         case AF_INET:
811           GNUNET_assert(addrlen == sizeof(struct sockaddr_in));
812           v4 = (const struct sockaddr_in *)&sa;
813           ok = (((NULL == sh->v4_allowed) ||
814                  (check_ipv4_listed(sh->v4_allowed, &v4->sin_addr))) &&
815                 ((NULL == sh->v4_denied) ||
816                  (!check_ipv4_listed(sh->v4_denied, &v4->sin_addr))));
817           break;
818
819         case AF_INET6:
820           GNUNET_assert(addrlen == sizeof(struct sockaddr_in6));
821           v6 = (const struct sockaddr_in6 *)&sa;
822           ok = (((NULL == sh->v6_allowed) ||
823                  (check_ipv6_listed(sh->v6_allowed, &v6->sin6_addr))) &&
824                 ((NULL == sh->v6_denied) ||
825                  (!check_ipv6_listed(sh->v6_denied, &v6->sin6_addr))));
826           break;
827
828 #ifndef WINDOWS
829         case AF_UNIX:
830           ok = GNUNET_OK; /* controlled using file-system ACL now */
831           break;
832 #endif
833         default:
834           LOG(GNUNET_ERROR_TYPE_WARNING,
835               _("Unknown address family %d\n"),
836               sa.ss_family);
837           return;
838         }
839       if (!ok)
840         {
841           LOG(GNUNET_ERROR_TYPE_DEBUG,
842               "Service rejected incoming connection from %s due to policy.\n",
843               GNUNET_a2s((const struct sockaddr *)&sa, addrlen));
844           GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(sock));
845           continue;
846         }
847       LOG(GNUNET_ERROR_TYPE_DEBUG,
848           "Service accepted incoming connection from %s.\n",
849           GNUNET_a2s((const struct sockaddr *)&sa, addrlen));
850       start_client(slc->sh, sock);
851     }
852   if (0 != sh->suspend_state)
853     return;
854   slc->listen_task =
855     GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL,
856                                   slc->listen_socket,
857                                   &accept_client,
858                                   slc);
859 }
860
861
862 /**
863  * Resume accepting connections from the listen socket.
864  *
865  * @param sh service to resume accepting connections.
866  * @param sr reason that is no longer causing the suspension,
867  *           or #SUSPEND_STATE_NONE on first startup
868  */
869 static void
870 do_resume(struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr)
871 {
872   struct ServiceListenContext *slc;
873
874   GNUNET_assert((SUSPEND_STATE_NONE == sr) || (0 != (sh->suspend_state & sr)));
875   sh->suspend_state -= sr;
876   if (SUSPEND_STATE_NONE != sh->suspend_state)
877     return;
878   for (slc = sh->slc_head; NULL != slc; slc = slc->next)
879     {
880       GNUNET_assert(NULL == slc->listen_task);
881       slc->listen_task =
882         GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL,
883                                       slc->listen_socket,
884                                       &accept_client,
885                                       slc);
886     }
887 }
888
889
890 /**
891  * First task run by any service.  Initializes our shutdown task,
892  * starts the listening operation on our listen sockets and launches
893  * the custom logic of the application service.
894  *
895  * @param cls our `struct GNUNET_SERVICE_Handle`
896  */
897 static void
898 service_main(void *cls)
899 {
900   struct GNUNET_SERVICE_Handle *sh = cls;
901
902   if (GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN != sh->options)
903     GNUNET_SCHEDULER_add_shutdown(&service_shutdown, sh);
904   do_resume(sh, SUSPEND_STATE_NONE);
905
906   if (-1 != sh->ready_confirm_fd)
907     {
908       GNUNET_break(1 == write(sh->ready_confirm_fd, ".", 1));
909       GNUNET_break(0 == close(sh->ready_confirm_fd));
910       sh->ready_confirm_fd = -1;
911     }
912
913   if (NULL != sh->service_init_cb)
914     sh->service_init_cb(sh->cb_cls, sh->cfg, sh);
915 }
916
917
918 /**
919  * Parse an IPv4 access control list.
920  *
921  * @param ret location where to write the ACL (set)
922  * @param sh service context to use to get the configuration
923  * @param option name of the ACL option to parse
924  * @return #GNUNET_SYSERR on parse error, #GNUNET_OK on success (including
925  *         no ACL configured)
926  */
927 static int
928 process_acl4(struct GNUNET_STRINGS_IPv4NetworkPolicy **ret,
929              struct GNUNET_SERVICE_Handle *sh,
930              const char *option)
931 {
932   char *opt;
933
934   if (!GNUNET_CONFIGURATION_have_value(sh->cfg, sh->service_name, option))
935     {
936       *ret = NULL;
937       return GNUNET_OK;
938     }
939   GNUNET_break(GNUNET_OK ==
940                GNUNET_CONFIGURATION_get_value_string(sh->cfg,
941                                                      sh->service_name,
942                                                      option,
943                                                      &opt));
944   if (NULL == (*ret = GNUNET_STRINGS_parse_ipv4_policy(opt)))
945     {
946       LOG(GNUNET_ERROR_TYPE_WARNING,
947           _("Could not parse IPv4 network specification `%s' for `%s:%s'\n"),
948           opt,
949           sh->service_name,
950           option);
951       GNUNET_free(opt);
952       return GNUNET_SYSERR;
953     }
954   GNUNET_free(opt);
955   return GNUNET_OK;
956 }
957
958
959 /**
960  * Parse an IPv6 access control list.
961  *
962  * @param ret location where to write the ACL (set)
963  * @param sh service context to use to get the configuration
964  * @param option name of the ACL option to parse
965  * @return #GNUNET_SYSERR on parse error, #GNUNET_OK on success (including
966  *         no ACL configured)
967  */
968 static int
969 process_acl6(struct GNUNET_STRINGS_IPv6NetworkPolicy **ret,
970              struct GNUNET_SERVICE_Handle *sh,
971              const char *option)
972 {
973   char *opt;
974
975   if (!GNUNET_CONFIGURATION_have_value(sh->cfg, sh->service_name, option))
976     {
977       *ret = NULL;
978       return GNUNET_OK;
979     }
980   GNUNET_break(GNUNET_OK ==
981                GNUNET_CONFIGURATION_get_value_string(sh->cfg,
982                                                      sh->service_name,
983                                                      option,
984                                                      &opt));
985   if (NULL == (*ret = GNUNET_STRINGS_parse_ipv6_policy(opt)))
986     {
987       LOG(GNUNET_ERROR_TYPE_WARNING,
988           _("Could not parse IPv6 network specification `%s' for `%s:%s'\n"),
989           opt,
990           sh->service_name,
991           option);
992       GNUNET_free(opt);
993       return GNUNET_SYSERR;
994     }
995   GNUNET_free(opt);
996   return GNUNET_OK;
997 }
998
999
1000 /**
1001  * Add the given UNIX domain path as an address to the
1002  * list (as the first entry).
1003  *
1004  * @param saddrs array to update
1005  * @param saddrlens where to store the address length
1006  * @param unixpath path to add
1007  * @param abstract #GNUNET_YES to add an abstract UNIX domain socket.  This
1008  *          parameter is ignore on systems other than LINUX
1009  */
1010 static void
1011 add_unixpath(struct sockaddr **saddrs,
1012              socklen_t *saddrlens,
1013              const char *unixpath,
1014              int abstract)
1015 {
1016 #ifdef AF_UNIX
1017   struct sockaddr_un *un;
1018
1019   un = GNUNET_new(struct sockaddr_un);
1020   un->sun_family = AF_UNIX;
1021   GNUNET_strlcpy(un->sun_path, unixpath, sizeof(un->sun_path));
1022 #ifdef LINUX
1023   if (GNUNET_YES == abstract)
1024     un->sun_path[0] = '\0';
1025 #endif
1026 #if HAVE_SOCKADDR_UN_SUN_LEN
1027   un->sun_len = (u_char)sizeof(struct sockaddr_un);
1028 #endif
1029   *saddrs = (struct sockaddr *)un;
1030   *saddrlens = sizeof(struct sockaddr_un);
1031 #else
1032   /* this function should never be called
1033    * unless AF_UNIX is defined! */
1034   GNUNET_assert(0);
1035 #endif
1036 }
1037
1038
1039 /**
1040  * Get the list of addresses that a server for the given service
1041  * should bind to.
1042  *
1043  * @param service_name name of the service
1044  * @param cfg configuration (which specifies the addresses)
1045  * @param addrs set (call by reference) to an array of pointers to the
1046  *              addresses the server should bind to and listen on; the
1047  *              array will be NULL-terminated (on success)
1048  * @param addr_lens set (call by reference) to an array of the lengths
1049  *              of the respective `struct sockaddr` struct in the @a addrs
1050  *              array (on success)
1051  * @return number of addresses found on success,
1052  *              #GNUNET_SYSERR if the configuration
1053  *              did not specify reasonable finding information or
1054  *              if it specified a hostname that could not be resolved;
1055  *              #GNUNET_NO if the number of addresses configured is
1056  *              zero (in this case, `*addrs` and `*addr_lens` will be
1057  *              set to NULL).
1058  */
1059 static int
1060 get_server_addresses(const char *service_name,
1061                      const struct GNUNET_CONFIGURATION_Handle *cfg,
1062                      struct sockaddr ***addrs,
1063                      socklen_t **addr_lens)
1064 {
1065   int disablev6;
1066   struct GNUNET_NETWORK_Handle *desc;
1067   unsigned long long port;
1068   char *unixpath;
1069   struct addrinfo hints;
1070   struct addrinfo *res;
1071   struct addrinfo *pos;
1072   struct addrinfo *next;
1073   unsigned int i;
1074   int resi;
1075   int ret;
1076   int abstract;
1077   struct sockaddr **saddrs;
1078   socklen_t *saddrlens;
1079   char *hostname;
1080
1081   *addrs = NULL;
1082   *addr_lens = NULL;
1083   desc = NULL;
1084   disablev6 = GNUNET_NO;
1085   if ((GNUNET_NO == GNUNET_NETWORK_test_pf(PF_INET6)) ||
1086       (GNUNET_YES ==
1087        GNUNET_CONFIGURATION_get_value_yesno(cfg, service_name, "DISABLEV6")))
1088     disablev6 = GNUNET_YES;
1089
1090   port = 0;
1091   if (GNUNET_CONFIGURATION_have_value(cfg, service_name, "PORT"))
1092     {
1093       if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number(cfg,
1094                                                              service_name,
1095                                                              "PORT",
1096                                                              &port))
1097         {
1098           LOG(GNUNET_ERROR_TYPE_ERROR,
1099               _("Require valid port number for service `%s' in configuration!\n"),
1100               service_name);
1101         }
1102       if (port > 65535)
1103         {
1104           LOG(GNUNET_ERROR_TYPE_ERROR,
1105               _("Require valid port number for service `%s' in configuration!\n"),
1106               service_name);
1107           return GNUNET_SYSERR;
1108         }
1109     }
1110
1111   if (GNUNET_CONFIGURATION_have_value(cfg, service_name, "BINDTO"))
1112     {
1113       GNUNET_break(GNUNET_OK ==
1114                    GNUNET_CONFIGURATION_get_value_string(cfg,
1115                                                          service_name,
1116                                                          "BINDTO",
1117                                                          &hostname));
1118     }
1119   else
1120     hostname = NULL;
1121
1122   unixpath = NULL;
1123   abstract = GNUNET_NO;
1124 #ifdef AF_UNIX
1125   if ((GNUNET_YES ==
1126        GNUNET_CONFIGURATION_have_value(cfg, service_name, "UNIXPATH")) &&
1127       (GNUNET_OK == GNUNET_CONFIGURATION_get_value_filename(cfg,
1128                                                             service_name,
1129                                                             "UNIXPATH",
1130                                                             &unixpath)) &&
1131       (0 < strlen(unixpath)))
1132     {
1133       /* probe UNIX support */
1134       struct sockaddr_un s_un;
1135
1136       if (strlen(unixpath) >= sizeof(s_un.sun_path))
1137         {
1138           LOG(GNUNET_ERROR_TYPE_WARNING,
1139               _("UNIXPATH `%s' too long, maximum length is %llu\n"),
1140               unixpath,
1141               (unsigned long long)sizeof(s_un.sun_path));
1142           unixpath = GNUNET_NETWORK_shorten_unixpath(unixpath);
1143           LOG(GNUNET_ERROR_TYPE_INFO, _("Using `%s' instead\n"), unixpath);
1144         }
1145 #ifdef LINUX
1146       abstract = GNUNET_CONFIGURATION_get_value_yesno(cfg,
1147                                                       "TESTING",
1148                                                       "USE_ABSTRACT_SOCKETS");
1149       if (GNUNET_SYSERR == abstract)
1150         abstract = GNUNET_NO;
1151 #endif
1152       if ((GNUNET_YES != abstract) &&
1153           (GNUNET_OK != GNUNET_DISK_directory_create_for_file(unixpath)))
1154         GNUNET_log_strerror_file(GNUNET_ERROR_TYPE_ERROR, "mkdir", unixpath);
1155     }
1156   if (NULL != unixpath)
1157     {
1158       desc = GNUNET_NETWORK_socket_create(AF_UNIX, SOCK_STREAM, 0);
1159       if (NULL == desc)
1160         {
1161           if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) ||
1162               (EACCES == errno))
1163             {
1164               LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "socket");
1165               GNUNET_free_non_null(hostname);
1166               GNUNET_free(unixpath);
1167               return GNUNET_SYSERR;
1168             }
1169           LOG(GNUNET_ERROR_TYPE_INFO,
1170               _(
1171                 "Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"),
1172               service_name,
1173               strerror(errno));
1174           GNUNET_free(unixpath);
1175           unixpath = NULL;
1176         }
1177       else
1178         {
1179           GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(desc));
1180           desc = NULL;
1181         }
1182     }
1183 #endif
1184
1185   if ((0 == port) && (NULL == unixpath))
1186     {
1187       LOG(GNUNET_ERROR_TYPE_ERROR,
1188           _(
1189             "Have neither PORT nor UNIXPATH for service `%s', but one is required\n"),
1190           service_name);
1191       GNUNET_free_non_null(hostname);
1192       return GNUNET_SYSERR;
1193     }
1194   if (0 == port)
1195     {
1196       saddrs = GNUNET_new_array(2, struct sockaddr *);
1197       saddrlens = GNUNET_new_array(2, socklen_t);
1198       add_unixpath(saddrs, saddrlens, unixpath, abstract);
1199       GNUNET_free_non_null(unixpath);
1200       GNUNET_free_non_null(hostname);
1201       *addrs = saddrs;
1202       *addr_lens = saddrlens;
1203       return 1;
1204     }
1205
1206   if (NULL != hostname)
1207     {
1208       LOG(GNUNET_ERROR_TYPE_DEBUG,
1209           "Resolving `%s' since that is where `%s' will bind to.\n",
1210           hostname,
1211           service_name);
1212       memset(&hints, 0, sizeof(struct addrinfo));
1213       if (disablev6)
1214         hints.ai_family = AF_INET;
1215       hints.ai_protocol = IPPROTO_TCP;
1216       if ((0 != (ret = getaddrinfo(hostname, NULL, &hints, &res))) ||
1217           (NULL == res))
1218         {
1219           LOG(GNUNET_ERROR_TYPE_ERROR,
1220               _("Failed to resolve `%s': %s\n"),
1221               hostname,
1222               gai_strerror(ret));
1223           GNUNET_free(hostname);
1224           GNUNET_free_non_null(unixpath);
1225           return GNUNET_SYSERR;
1226         }
1227       next = res;
1228       i = 0;
1229       while (NULL != (pos = next))
1230         {
1231           next = pos->ai_next;
1232           if ((disablev6) && (pos->ai_family == AF_INET6))
1233             continue;
1234           i++;
1235         }
1236       if (0 == i)
1237         {
1238           LOG(GNUNET_ERROR_TYPE_ERROR,
1239               _("Failed to find %saddress for `%s'.\n"),
1240               disablev6 ? "IPv4 " : "",
1241               hostname);
1242           freeaddrinfo(res);
1243           GNUNET_free(hostname);
1244           GNUNET_free_non_null(unixpath);
1245           return GNUNET_SYSERR;
1246         }
1247       resi = i;
1248       if (NULL != unixpath)
1249         resi++;
1250       saddrs = GNUNET_new_array(resi + 1, struct sockaddr *);
1251       saddrlens = GNUNET_new_array(resi + 1, socklen_t);
1252       i = 0;
1253       if (NULL != unixpath)
1254         {
1255           add_unixpath(saddrs, saddrlens, unixpath, abstract);
1256           i++;
1257         }
1258       next = res;
1259       while (NULL != (pos = next))
1260         {
1261           next = pos->ai_next;
1262           if ((disablev6) && (AF_INET6 == pos->ai_family))
1263             continue;
1264           if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol))
1265             continue; /* not TCP */
1266           if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype))
1267             continue; /* huh? */
1268           LOG(GNUNET_ERROR_TYPE_DEBUG,
1269               "Service `%s' will bind to `%s'\n",
1270               service_name,
1271               GNUNET_a2s(pos->ai_addr, pos->ai_addrlen));
1272           if (AF_INET == pos->ai_family)
1273             {
1274               GNUNET_assert(sizeof(struct sockaddr_in) == pos->ai_addrlen);
1275               saddrlens[i] = pos->ai_addrlen;
1276               saddrs[i] = GNUNET_malloc(saddrlens[i]);
1277               GNUNET_memcpy(saddrs[i], pos->ai_addr, saddrlens[i]);
1278               ((struct sockaddr_in *)saddrs[i])->sin_port = htons(port);
1279             }
1280           else
1281             {
1282               GNUNET_assert(AF_INET6 == pos->ai_family);
1283               GNUNET_assert(sizeof(struct sockaddr_in6) == pos->ai_addrlen);
1284               saddrlens[i] = pos->ai_addrlen;
1285               saddrs[i] = GNUNET_malloc(saddrlens[i]);
1286               GNUNET_memcpy(saddrs[i], pos->ai_addr, saddrlens[i]);
1287               ((struct sockaddr_in6 *)saddrs[i])->sin6_port = htons(port);
1288             }
1289           i++;
1290         }
1291       GNUNET_free(hostname);
1292       freeaddrinfo(res);
1293       resi = i;
1294     }
1295   else
1296     {
1297       /* will bind against everything, just set port */
1298       if (disablev6)
1299         {
1300           /* V4-only */
1301           resi = 1;
1302           if (NULL != unixpath)
1303             resi++;
1304           i = 0;
1305           saddrs = GNUNET_new_array(resi + 1, struct sockaddr *);
1306           saddrlens = GNUNET_new_array(resi + 1, socklen_t);
1307           if (NULL != unixpath)
1308             {
1309               add_unixpath(saddrs, saddrlens, unixpath, abstract);
1310               i++;
1311             }
1312           saddrlens[i] = sizeof(struct sockaddr_in);
1313           saddrs[i] = GNUNET_malloc(saddrlens[i]);
1314 #if HAVE_SOCKADDR_IN_SIN_LEN
1315           ((struct sockaddr_in *)saddrs[i])->sin_len = saddrlens[i];
1316 #endif
1317           ((struct sockaddr_in *)saddrs[i])->sin_family = AF_INET;
1318           ((struct sockaddr_in *)saddrs[i])->sin_port = htons(port);
1319         }
1320       else
1321         {
1322           /* dual stack */
1323           resi = 2;
1324           if (NULL != unixpath)
1325             resi++;
1326           saddrs = GNUNET_new_array(resi + 1, struct sockaddr *);
1327           saddrlens = GNUNET_new_array(resi + 1, socklen_t);
1328           i = 0;
1329           if (NULL != unixpath)
1330             {
1331               add_unixpath(saddrs, saddrlens, unixpath, abstract);
1332               i++;
1333             }
1334           saddrlens[i] = sizeof(struct sockaddr_in6);
1335           saddrs[i] = GNUNET_malloc(saddrlens[i]);
1336 #if HAVE_SOCKADDR_IN_SIN_LEN
1337           ((struct sockaddr_in6 *)saddrs[i])->sin6_len = saddrlens[0];
1338 #endif
1339           ((struct sockaddr_in6 *)saddrs[i])->sin6_family = AF_INET6;
1340           ((struct sockaddr_in6 *)saddrs[i])->sin6_port = htons(port);
1341           i++;
1342           saddrlens[i] = sizeof(struct sockaddr_in);
1343           saddrs[i] = GNUNET_malloc(saddrlens[i]);
1344 #if HAVE_SOCKADDR_IN_SIN_LEN
1345           ((struct sockaddr_in *)saddrs[i])->sin_len = saddrlens[1];
1346 #endif
1347           ((struct sockaddr_in *)saddrs[i])->sin_family = AF_INET;
1348           ((struct sockaddr_in *)saddrs[i])->sin_port = htons(port);
1349         }
1350     }
1351   GNUNET_free_non_null(unixpath);
1352   *addrs = saddrs;
1353   *addr_lens = saddrlens;
1354   return resi;
1355 }
1356
1357
1358 #ifdef MINGW
1359 /**
1360  * Read listen sockets from the parent process (ARM).
1361  *
1362  * @param sh service context to initialize
1363  * @return NULL-terminated array of sockets on success,
1364  *         NULL if not ok (must bind yourself)
1365  */
1366 static struct GNUNET_NETWORK_Handle **
1367 receive_sockets_from_parent(struct GNUNET_SERVICE_Handle *sh)
1368 {
1369   static struct GNUNET_NETWORK_Handle **lsocks;
1370   const char *env_buf;
1371   int fail;
1372   uint64_t count;
1373   uint64_t i;
1374   HANDLE lsocks_pipe;
1375
1376   env_buf = getenv("GNUNET_OS_READ_LSOCKS");
1377   if ((NULL == env_buf) || (strlen(env_buf) <= 0))
1378     return NULL;
1379   /* Using W32 API directly here, because this pipe will
1380    * never be used outside of this function, and it's just too much of a bother
1381    * to create a GNUnet API that boxes a HANDLE (the way it is done with socks)
1382    */
1383   lsocks_pipe = (HANDLE)strtoul(env_buf, NULL, 10);
1384   if ((0 == lsocks_pipe) || (INVALID_HANDLE_VALUE == lsocks_pipe))
1385     return NULL;
1386   fail = 1;
1387   do
1388     {
1389       int ret;
1390       int fail2;
1391       DWORD rd;
1392
1393       ret = ReadFile(lsocks_pipe, &count, sizeof(count), &rd, NULL);
1394       if ((0 == ret) || (sizeof(count) != rd) || (0 == count))
1395         break;
1396       lsocks = GNUNET_new_array(count + 1, struct GNUNET_NETWORK_Handle *);
1397
1398       fail2 = 1;
1399       for (i = 0; i < count; i++)
1400         {
1401           WSAPROTOCOL_INFOA pi;
1402           uint64_t size;
1403           SOCKET s;
1404
1405           ret = ReadFile(lsocks_pipe, &size, sizeof(size), &rd, NULL);
1406           if ((0 == ret) || (sizeof(size) != rd) || (sizeof(pi) != size))
1407             break;
1408           ret = ReadFile(lsocks_pipe, &pi, sizeof(pi), &rd, NULL);
1409           if ((0 == ret) || (sizeof(pi) != rd))
1410             break;
1411           s = WSASocketA(pi.iAddressFamily,
1412                          pi.iSocketType,
1413                          pi.iProtocol,
1414                          &pi,
1415                          0,
1416                          WSA_FLAG_OVERLAPPED);
1417           lsocks[i] = GNUNET_NETWORK_socket_box_native(s);
1418           if (NULL == lsocks[i])
1419             break;
1420           else if (i == count - 1)
1421             fail2 = 0;
1422         }
1423       if (fail2)
1424         break;
1425       lsocks[count] = NULL;
1426       fail = 0;
1427     }
1428   while (fail);
1429   CloseHandle(lsocks_pipe);
1430
1431   if (fail)
1432     {
1433       LOG(GNUNET_ERROR_TYPE_ERROR,
1434           _("Could not access a pre-bound socket, will try to bind myself\n"));
1435       for (i = 0; (i < count) && (NULL != lsocks[i]); i++)
1436         GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(lsocks[i]));
1437       GNUNET_free(lsocks);
1438       return NULL;
1439     }
1440   return lsocks;
1441 }
1442 #endif
1443
1444
1445 /**
1446  * Create and initialize a listen socket for the server.
1447  *
1448  * @param server_addr address to listen on
1449  * @param socklen length of @a server_addr
1450  * @return NULL on error, otherwise the listen socket
1451  */
1452 static struct GNUNET_NETWORK_Handle *
1453 open_listen_socket(const struct sockaddr *server_addr, socklen_t socklen)
1454 {
1455   struct GNUNET_NETWORK_Handle *sock;
1456   uint16_t port;
1457   int eno;
1458
1459   switch (server_addr->sa_family)
1460     {
1461     case AF_INET:
1462       port = ntohs(((const struct sockaddr_in *)server_addr)->sin_port);
1463       break;
1464
1465     case AF_INET6:
1466       port = ntohs(((const struct sockaddr_in6 *)server_addr)->sin6_port);
1467       break;
1468
1469     case AF_UNIX:
1470       port = 0;
1471       break;
1472
1473     default:
1474       GNUNET_break(0);
1475       port = 0;
1476       break;
1477     }
1478   sock = GNUNET_NETWORK_socket_create(server_addr->sa_family, SOCK_STREAM, 0);
1479   if (NULL == sock)
1480     {
1481       LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "socket");
1482       errno = 0;
1483       return NULL;
1484     }
1485   /* bind the socket */
1486   if (GNUNET_OK != GNUNET_NETWORK_socket_bind(sock, server_addr, socklen))
1487     {
1488       eno = errno;
1489       if (EADDRINUSE != errno)
1490         {
1491           /* we don't log 'EADDRINUSE' here since an IPv4 bind may
1492            * fail if we already took the port on IPv6; if both IPv4 and
1493            * IPv6 binds fail, then our caller will log using the
1494            * errno preserved in 'eno' */
1495           if (0 != port)
1496             LOG(GNUNET_ERROR_TYPE_ERROR,
1497                 _("`%s' failed for port %d (%s).\n"),
1498                 "bind",
1499                 port,
1500                 (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
1501           else
1502             LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "bind");
1503           eno = 0;
1504         }
1505       else
1506         {
1507           if (0 != port)
1508             LOG(GNUNET_ERROR_TYPE_WARNING,
1509                 _("`%s' failed for port %d (%s): address already in use\n"),
1510                 "bind",
1511                 port,
1512                 (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
1513           else if (AF_UNIX == server_addr->sa_family)
1514             {
1515               LOG(GNUNET_ERROR_TYPE_WARNING,
1516                   _("`%s' failed for `%s': address already in use\n"),
1517                   "bind",
1518                   GNUNET_a2s(server_addr, socklen));
1519             }
1520         }
1521       GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(sock));
1522       errno = eno;
1523       return NULL;
1524     }
1525   if (GNUNET_OK != GNUNET_NETWORK_socket_listen(sock, 5))
1526     {
1527       LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "listen");
1528       GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(sock));
1529       errno = 0;
1530       return NULL;
1531     }
1532   if (0 != port)
1533     LOG(GNUNET_ERROR_TYPE_DEBUG,
1534         "Server starts to listen on port %u.\n",
1535         port);
1536   return sock;
1537 }
1538
1539
1540 /**
1541  * Setup service handle
1542  *
1543  * Configuration may specify:
1544  * - PORT (where to bind to for TCP)
1545  * - UNIXPATH (where to bind to for UNIX domain sockets)
1546  * - DISABLEV6 (disable support for IPv6, otherwise we use dual-stack)
1547  * - BINDTO (hostname or IP address to bind to, otherwise we take everything)
1548  * - ACCEPT_FROM  (only allow connections from specified IPv4 subnets)
1549  * - ACCEPT_FROM6 (only allow connections from specified IPv6 subnets)
1550  * - REJECT_FROM  (disallow allow connections from specified IPv4 subnets)
1551  * - REJECT_FROM6 (disallow allow connections from specified IPv6 subnets)
1552  *
1553  * @param sh service context to initialize
1554  * @return #GNUNET_OK if configuration succeeded
1555  */
1556 static int
1557 setup_service(struct GNUNET_SERVICE_Handle *sh)
1558 {
1559   int tolerant;
1560   struct GNUNET_NETWORK_Handle **lsocks;
1561
1562 #ifndef MINGW
1563   const char *nfds;
1564   unsigned int cnt;
1565   int flags;
1566   char dummy[2];
1567 #endif
1568
1569   if (GNUNET_CONFIGURATION_have_value(sh->cfg, sh->service_name, "TOLERANT"))
1570     {
1571       if (GNUNET_SYSERR ==
1572           (tolerant = GNUNET_CONFIGURATION_get_value_yesno(sh->cfg,
1573                                                            sh->service_name,
1574                                                            "TOLERANT")))
1575         {
1576           LOG(GNUNET_ERROR_TYPE_ERROR,
1577               _("Specified value for `%s' of service `%s' is invalid\n"),
1578               "TOLERANT",
1579               sh->service_name);
1580           return GNUNET_SYSERR;
1581         }
1582     }
1583   else
1584     tolerant = GNUNET_NO;
1585
1586   lsocks = NULL;
1587 #ifndef MINGW
1588   errno = 0;
1589   if ((NULL != (nfds = getenv("LISTEN_FDS"))) &&
1590       (1 == sscanf(nfds, "%u%1s", &cnt, dummy)) && (cnt > 0) &&
1591       (cnt < FD_SETSIZE) && (cnt + 4 < FD_SETSIZE))
1592     {
1593       lsocks = GNUNET_new_array(cnt + 1, struct GNUNET_NETWORK_Handle *);
1594       while (0 < cnt--)
1595         {
1596           flags = fcntl(3 + cnt, F_GETFD);
1597           if ((flags < 0) || (0 != (flags & FD_CLOEXEC)) ||
1598               (NULL == (lsocks[cnt] = GNUNET_NETWORK_socket_box_native(3 + cnt))))
1599             {
1600               LOG(GNUNET_ERROR_TYPE_ERROR,
1601                   _(
1602                     "Could not access pre-bound socket %u, will try to bind myself\n"),
1603                   (unsigned int)3 + cnt);
1604               cnt++;
1605               while (NULL != lsocks[cnt])
1606                 GNUNET_break(GNUNET_OK ==
1607                              GNUNET_NETWORK_socket_close(lsocks[cnt++]));
1608               GNUNET_free(lsocks);
1609               lsocks = NULL;
1610               break;
1611             }
1612         }
1613       unsetenv("LISTEN_FDS");
1614     }
1615 #else
1616   if (NULL != getenv("GNUNET_OS_READ_LSOCKS"))
1617     {
1618       lsocks = receive_sockets_from_parent(sh);
1619       putenv("GNUNET_OS_READ_LSOCKS=");
1620     }
1621 #endif
1622
1623   if (NULL != lsocks)
1624     {
1625       /* listen only on inherited sockets if we have any */
1626       struct GNUNET_NETWORK_Handle **ls;
1627
1628       for (ls = lsocks; NULL != *ls; ls++)
1629         {
1630           struct ServiceListenContext *slc;
1631
1632           slc = GNUNET_new(struct ServiceListenContext);
1633           slc->sh = sh;
1634           slc->listen_socket = *ls;
1635           GNUNET_CONTAINER_DLL_insert(sh->slc_head, sh->slc_tail, slc);
1636         }
1637       GNUNET_free(lsocks);
1638     }
1639   else
1640     {
1641       struct sockaddr **addrs;
1642       socklen_t *addrlens;
1643       int num;
1644
1645       num = get_server_addresses(sh->service_name, sh->cfg, &addrs, &addrlens);
1646       if (GNUNET_SYSERR == num)
1647         return GNUNET_SYSERR;
1648
1649       for (int i = 0; i < num; i++)
1650         {
1651           struct ServiceListenContext *slc;
1652
1653           slc = GNUNET_new(struct ServiceListenContext);
1654           slc->sh = sh;
1655           slc->listen_socket = open_listen_socket(addrs[i], addrlens[i]);
1656           GNUNET_free(addrs[i]);
1657           if (NULL == slc->listen_socket)
1658             {
1659               GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR, "bind");
1660               GNUNET_free(slc);
1661               continue;
1662             }
1663           GNUNET_CONTAINER_DLL_insert(sh->slc_head, sh->slc_tail, slc);
1664         }
1665       GNUNET_free_non_null(addrlens);
1666       GNUNET_free_non_null(addrs);
1667       if ((0 != num) && (NULL == sh->slc_head))
1668         {
1669           /* All attempts to bind failed, hard failure */
1670           GNUNET_log(
1671             GNUNET_ERROR_TYPE_ERROR,
1672             _(
1673               "Could not bind to any of the ports I was supposed to, refusing to run!\n"));
1674           return GNUNET_SYSERR;
1675         }
1676     }
1677
1678   sh->require_found = tolerant ? GNUNET_NO : GNUNET_YES;
1679   sh->match_uid = GNUNET_CONFIGURATION_get_value_yesno(sh->cfg,
1680                                                        sh->service_name,
1681                                                        "UNIX_MATCH_UID");
1682   sh->match_gid = GNUNET_CONFIGURATION_get_value_yesno(sh->cfg,
1683                                                        sh->service_name,
1684                                                        "UNIX_MATCH_GID");
1685   process_acl4(&sh->v4_denied, sh, "REJECT_FROM");
1686   process_acl4(&sh->v4_allowed, sh, "ACCEPT_FROM");
1687   process_acl6(&sh->v6_denied, sh, "REJECT_FROM6");
1688   process_acl6(&sh->v6_allowed, sh, "ACCEPT_FROM6");
1689   return GNUNET_OK;
1690 }
1691
1692
1693 /**
1694  * Get the name of the user that'll be used
1695  * to provide the service.
1696  *
1697  * @param sh service context
1698  * @return value of the 'USERNAME' option
1699  */
1700 static char *
1701 get_user_name(struct GNUNET_SERVICE_Handle *sh)
1702 {
1703   char *un;
1704
1705   if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename(sh->cfg,
1706                                                            sh->service_name,
1707                                                            "USERNAME",
1708                                                            &un))
1709     return NULL;
1710   return un;
1711 }
1712
1713
1714 /**
1715  * Set user ID.
1716  *
1717  * @param sh service context
1718  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
1719  */
1720 static int
1721 set_user_id(struct GNUNET_SERVICE_Handle *sh)
1722 {
1723   char *user;
1724
1725   if (NULL == (user = get_user_name(sh)))
1726     return GNUNET_OK; /* keep */
1727 #ifndef MINGW
1728   struct passwd *pws;
1729
1730   errno = 0;
1731   pws = getpwnam(user);
1732   if (NULL == pws)
1733     {
1734       LOG(GNUNET_ERROR_TYPE_ERROR,
1735           _("Cannot obtain information about user `%s': %s\n"),
1736           user,
1737           errno == 0 ? _("No such user") : strerror(errno));
1738       GNUNET_free(user);
1739       return GNUNET_SYSERR;
1740     }
1741   if ((0 != setgid(pws->pw_gid)) || (0 != setegid(pws->pw_gid)) ||
1742 #if HAVE_INITGROUPS
1743       (0 != initgroups(user, pws->pw_gid)) ||
1744 #endif
1745       (0 != setuid(pws->pw_uid)) || (0 != seteuid(pws->pw_uid)))
1746     {
1747       if ((0 != setregid(pws->pw_gid, pws->pw_gid)) ||
1748           (0 != setreuid(pws->pw_uid, pws->pw_uid)))
1749         {
1750           LOG(GNUNET_ERROR_TYPE_ERROR,
1751               _("Cannot change user/group to `%s': %s\n"),
1752               user,
1753               strerror(errno));
1754           GNUNET_free(user);
1755           return GNUNET_SYSERR;
1756         }
1757     }
1758 #endif
1759   GNUNET_free(user);
1760   return GNUNET_OK;
1761 }
1762
1763
1764 /**
1765  * Get the name of the file where we will
1766  * write the PID of the service.
1767  *
1768  * @param sh service context
1769  * @return name of the file for the process ID
1770  */
1771 static char *
1772 get_pid_file_name(struct GNUNET_SERVICE_Handle *sh)
1773 {
1774   char *pif;
1775
1776   if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename(sh->cfg,
1777                                                            sh->service_name,
1778                                                            "PIDFILE",
1779                                                            &pif))
1780     return NULL;
1781   return pif;
1782 }
1783
1784
1785 /**
1786  * Delete the PID file that was created by our parent.
1787  *
1788  * @param sh service context
1789  */
1790 static void
1791 pid_file_delete(struct GNUNET_SERVICE_Handle *sh)
1792 {
1793   char *pif = get_pid_file_name(sh);
1794
1795   if (NULL == pif)
1796     return; /* no PID file */
1797   if (0 != unlink(pif))
1798     LOG_STRERROR_FILE(GNUNET_ERROR_TYPE_WARNING, "unlink", pif);
1799   GNUNET_free(pif);
1800 }
1801
1802
1803 /**
1804  * Detach from terminal.
1805  *
1806  * @param sh service context
1807  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
1808  */
1809 static int
1810 detach_terminal(struct GNUNET_SERVICE_Handle *sh)
1811 {
1812 #ifndef MINGW
1813   pid_t pid;
1814   int nullfd;
1815   int filedes[2];
1816
1817   if (0 != pipe(filedes))
1818     {
1819       LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "pipe");
1820       return GNUNET_SYSERR;
1821     }
1822   pid = fork();
1823   if (pid < 0)
1824     {
1825       LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "fork");
1826       return GNUNET_SYSERR;
1827     }
1828   if (0 != pid)
1829     {
1830       /* Parent */
1831       char c;
1832
1833       GNUNET_break(0 == close(filedes[1]));
1834       c = 'X';
1835       if (1 != read(filedes[0], &c, sizeof(char)))
1836         LOG_STRERROR(GNUNET_ERROR_TYPE_WARNING, "read");
1837       fflush(stdout);
1838       switch (c)
1839         {
1840         case '.':
1841           exit(0);
1842
1843         case 'I':
1844           LOG(GNUNET_ERROR_TYPE_INFO,
1845               _("Service process failed to initialize\n"));
1846           break;
1847
1848         case 'S':
1849           LOG(GNUNET_ERROR_TYPE_INFO,
1850               _("Service process could not initialize server function\n"));
1851           break;
1852
1853         case 'X':
1854           LOG(GNUNET_ERROR_TYPE_INFO,
1855               _("Service process failed to report status\n"));
1856           break;
1857         }
1858       exit(1); /* child reported error */
1859     }
1860   GNUNET_break(0 == close(0));
1861   GNUNET_break(0 == close(1));
1862   GNUNET_break(0 == close(filedes[0]));
1863   nullfd = open("/dev/null", O_RDWR | O_APPEND);
1864   if (nullfd < 0)
1865     return GNUNET_SYSERR;
1866   /* set stdin/stdout to /dev/null */
1867   if ((dup2(nullfd, 0) < 0) || (dup2(nullfd, 1) < 0))
1868     {
1869       LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "dup2");
1870       (void)close(nullfd);
1871       return GNUNET_SYSERR;
1872     }
1873   (void)close(nullfd);
1874   /* Detach from controlling terminal */
1875   pid = setsid();
1876   if (-1 == pid)
1877     LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "setsid");
1878   sh->ready_confirm_fd = filedes[1];
1879 #else
1880   /* FIXME: we probably need to do something else
1881    * elsewhere in order to fork the process itself... */
1882   FreeConsole();
1883 #endif
1884   return GNUNET_OK;
1885 }
1886
1887
1888 /**
1889  * Tear down the service, closing the listen sockets and
1890  * freeing the ACLs.
1891  *
1892  * @param sh handle to the service to tear down.
1893  */
1894 static void
1895 teardown_service(struct GNUNET_SERVICE_Handle *sh)
1896 {
1897   struct ServiceListenContext *slc;
1898
1899   GNUNET_free_non_null(sh->v4_denied);
1900   GNUNET_free_non_null(sh->v6_denied);
1901   GNUNET_free_non_null(sh->v4_allowed);
1902   GNUNET_free_non_null(sh->v6_allowed);
1903   while (NULL != (slc = sh->slc_head))
1904     {
1905       GNUNET_CONTAINER_DLL_remove(sh->slc_head, sh->slc_tail, slc);
1906       if (NULL != slc->listen_task)
1907         GNUNET_SCHEDULER_cancel(slc->listen_task);
1908       GNUNET_break(GNUNET_OK ==
1909                    GNUNET_NETWORK_socket_close(slc->listen_socket));
1910       GNUNET_free(slc);
1911     }
1912 }
1913
1914
1915 /**
1916  * Function to return link to AGPL source upon request.
1917  *
1918  * @param cls closure with the identification of the client
1919  * @param msg AGPL request
1920  */
1921 static void
1922 return_agpl(void *cls, const struct GNUNET_MessageHeader *msg)
1923 {
1924   struct GNUNET_SERVICE_Client *client = cls;
1925   struct GNUNET_MQ_Handle *mq;
1926   struct GNUNET_MQ_Envelope *env;
1927   struct GNUNET_MessageHeader *res;
1928   size_t slen;
1929
1930   (void)msg;
1931   slen = strlen(GNUNET_AGPL_URL) + 1;
1932   env = GNUNET_MQ_msg_extra(res, GNUNET_MESSAGE_TYPE_RESPONSE_AGPL, slen);
1933   memcpy(&res[1], GNUNET_AGPL_URL, slen);
1934   mq = GNUNET_SERVICE_client_get_mq(client);
1935   GNUNET_MQ_send(mq, env);
1936   GNUNET_SERVICE_client_continue(client);
1937 }
1938
1939
1940 /**
1941  * Low-level function to start a service if the scheduler
1942  * is already running.  Should only be used directly in
1943  * special cases.
1944  *
1945  * The function will launch the service with the name @a service_name
1946  * using the @a service_options to configure its shutdown
1947  * behavior. When clients connect or disconnect, the respective
1948  * @a connect_cb or @a disconnect_cb functions will be called. For
1949  * messages received from the clients, the respective @a handlers will
1950  * be invoked; for the closure of the handlers we use the return value
1951  * from the @a connect_cb invocation of the respective client.
1952  *
1953  * Each handler MUST call #GNUNET_SERVICE_client_continue() after each
1954  * message to receive further messages from this client.  If
1955  * #GNUNET_SERVICE_client_continue() is not called within a short
1956  * time, a warning will be logged. If delays are expected, services
1957  * should call #GNUNET_SERVICE_client_disable_continue_warning() to
1958  * disable the warning.
1959  *
1960  * Clients sending invalid messages (based on @a handlers) will be
1961  * dropped. Additionally, clients can be dropped at any time using
1962  * #GNUNET_SERVICE_client_drop().
1963  *
1964  * The service must be stopped using #GNUNET_SERVICE_stop().
1965  *
1966  * @param service_name name of the service to run
1967  * @param cfg configuration to use
1968  * @param connect_cb function to call whenever a client connects
1969  * @param disconnect_cb function to call whenever a client disconnects
1970  * @param cls closure argument for @a connect_cb and @a disconnect_cb
1971  * @param handlers NULL-terminated array of message handlers for the service,
1972  *                 the closure will be set to the value returned by
1973  *                 the @a connect_cb for the respective connection
1974  * @return NULL on error
1975  */
1976 struct GNUNET_SERVICE_Handle *
1977 GNUNET_SERVICE_start(const char *service_name,
1978                      const struct GNUNET_CONFIGURATION_Handle *cfg,
1979                      GNUNET_SERVICE_ConnectHandler connect_cb,
1980                      GNUNET_SERVICE_DisconnectHandler disconnect_cb,
1981                      void *cls,
1982                      const struct GNUNET_MQ_MessageHandler *handlers)
1983 {
1984   struct GNUNET_SERVICE_Handle *sh;
1985
1986   sh = GNUNET_new(struct GNUNET_SERVICE_Handle);
1987   sh->service_name = service_name;
1988   sh->cfg = cfg;
1989   sh->connect_cb = connect_cb;
1990   sh->disconnect_cb = disconnect_cb;
1991   sh->cb_cls = cls;
1992   sh->handlers = GNUNET_MQ_copy_handlers2(handlers, &return_agpl, NULL);
1993   if (GNUNET_OK != setup_service(sh))
1994     {
1995       GNUNET_free_non_null(sh->handlers);
1996       GNUNET_free(sh);
1997       return NULL;
1998     }
1999   do_resume(sh, SUSPEND_STATE_NONE);
2000   return sh;
2001 }
2002
2003
2004 /**
2005  * Stops a service that was started with #GNUNET_SERVICE_start().
2006  *
2007  * @param srv service to stop
2008  */
2009 void
2010 GNUNET_SERVICE_stop(struct GNUNET_SERVICE_Handle *srv)
2011 {
2012   struct GNUNET_SERVICE_Client *client;
2013
2014   GNUNET_SERVICE_suspend(srv);
2015   while (NULL != (client = srv->clients_head))
2016     GNUNET_SERVICE_client_drop(client);
2017   teardown_service(srv);
2018   GNUNET_free_non_null(srv->handlers);
2019   GNUNET_free(srv);
2020 }
2021
2022
2023 /**
2024  * Creates the "main" function for a GNUnet service.  You
2025  * should almost always use the #GNUNET_SERVICE_MAIN macro
2026  * instead of calling this function directly (except
2027  * for ARM, which should call this function directly).
2028  *
2029  * The function will launch the service with the name @a service_name
2030  * using the @a service_options to configure its shutdown
2031  * behavior. Once the service is ready, the @a init_cb will be called
2032  * for service-specific initialization.  @a init_cb will be given the
2033  * service handler which can be used to control the service's
2034  * availability.  When clients connect or disconnect, the respective
2035  * @a connect_cb or @a disconnect_cb functions will be called. For
2036  * messages received from the clients, the respective @a handlers will
2037  * be invoked; for the closure of the handlers we use the return value
2038  * from the @a connect_cb invocation of the respective client.
2039  *
2040  * Each handler MUST call #GNUNET_SERVICE_client_continue() after each
2041  * message to receive further messages from this client.  If
2042  * #GNUNET_SERVICE_client_continue() is not called within a short
2043  * time, a warning will be logged. If delays are expected, services
2044  * should call #GNUNET_SERVICE_client_disable_continue_warning() to
2045  * disable the warning.
2046  *
2047  * Clients sending invalid messages (based on @a handlers) will be
2048  * dropped. Additionally, clients can be dropped at any time using
2049  * #GNUNET_SERVICE_client_drop().
2050  *
2051  * @param argc number of command-line arguments in @a argv
2052  * @param argv array of command-line arguments
2053  * @param service_name name of the service to run
2054  * @param options options controlling shutdown of the service
2055  * @param service_init_cb function to call once the service is ready
2056  * @param connect_cb function to call whenever a client connects
2057  * @param disconnect_cb function to call whenever a client disconnects
2058  * @param cls closure argument for @a service_init_cb, @a connect_cb and @a disconnect_cb
2059  * @param handlers NULL-terminated array of message handlers for the service,
2060  *                 the closure will be set to the value returned by
2061  *                 the @a connect_cb for the respective connection
2062  * @return 0 on success, non-zero on error
2063  */
2064 int
2065 GNUNET_SERVICE_run_(int argc,
2066                     char *const *argv,
2067                     const char *service_name,
2068                     enum GNUNET_SERVICE_Options options,
2069                     GNUNET_SERVICE_InitCallback service_init_cb,
2070                     GNUNET_SERVICE_ConnectHandler connect_cb,
2071                     GNUNET_SERVICE_DisconnectHandler disconnect_cb,
2072                     void *cls,
2073                     const struct GNUNET_MQ_MessageHandler *handlers)
2074 {
2075   struct GNUNET_SERVICE_Handle sh;
2076
2077 #if ENABLE_NLS
2078   char *path;
2079 #endif
2080   char *cfg_filename;
2081   char *opt_cfg_filename;
2082   char *loglev;
2083   const char *xdg;
2084   char *logfile;
2085   int do_daemonize;
2086   unsigned long long skew_offset;
2087   unsigned long long skew_variance;
2088   long long clock_offset;
2089   struct GNUNET_CONFIGURATION_Handle *cfg;
2090   int ret;
2091   int err;
2092   const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get();
2093
2094   struct GNUNET_GETOPT_CommandLineOption service_options[] =
2095   { GNUNET_GETOPT_option_cfgfile(&opt_cfg_filename),
2096     GNUNET_GETOPT_option_flag('d',
2097                               "daemonize",
2098                               gettext_noop(
2099                                 "do daemonize (detach from terminal)"),
2100                               &do_daemonize),
2101     GNUNET_GETOPT_option_help(NULL),
2102     GNUNET_GETOPT_option_loglevel(&loglev),
2103     GNUNET_GETOPT_option_logfile(&logfile),
2104     GNUNET_GETOPT_option_version(pd->version),
2105     GNUNET_GETOPT_OPTION_END };
2106
2107   err = 1;
2108   memset(&sh, 0, sizeof(sh));
2109   xdg = getenv("XDG_CONFIG_HOME");
2110   if (NULL != xdg)
2111     GNUNET_asprintf(&cfg_filename,
2112                     "%s%s%s",
2113                     xdg,
2114                     DIR_SEPARATOR_STR,
2115                     pd->config_file);
2116   else
2117     cfg_filename = GNUNET_strdup(pd->user_config_file);
2118   sh.ready_confirm_fd = -1;
2119   sh.options = options;
2120   sh.cfg = cfg = GNUNET_CONFIGURATION_create();
2121   sh.service_init_cb = service_init_cb;
2122   sh.connect_cb = connect_cb;
2123   sh.disconnect_cb = disconnect_cb;
2124   sh.cb_cls = cls;
2125   sh.handlers = GNUNET_MQ_copy_handlers(handlers);
2126   sh.service_name = service_name;
2127   sh.ret = 0;
2128   /* setup subsystems */
2129   loglev = NULL;
2130   logfile = NULL;
2131   opt_cfg_filename = NULL;
2132   do_daemonize = 0;
2133 #if ENABLE_NLS
2134   if (NULL != pd->gettext_domain)
2135     {
2136       setlocale(LC_ALL, "");
2137       path = (NULL == pd->gettext_path) ?
2138              GNUNET_OS_installation_get_path(GNUNET_OS_IPK_LOCALEDIR) :
2139              GNUNET_strdup(pd->gettext_path);
2140       if (NULL != path)
2141         {
2142           bindtextdomain(pd->gettext_domain, path);
2143           GNUNET_free(path);
2144         }
2145       textdomain(pd->gettext_domain);
2146     }
2147 #endif
2148   ret = GNUNET_GETOPT_run(service_name, service_options, argc, argv);
2149   if (GNUNET_SYSERR == ret)
2150     goto shutdown;
2151   if (GNUNET_NO == ret)
2152     {
2153       err = 0;
2154       goto shutdown;
2155     }
2156   if (GNUNET_OK != GNUNET_log_setup(service_name, loglev, logfile))
2157     {
2158       GNUNET_break(0);
2159       goto shutdown;
2160     }
2161   if (NULL != opt_cfg_filename)
2162     {
2163       if ((GNUNET_YES != GNUNET_DISK_file_test(opt_cfg_filename)) ||
2164           (GNUNET_SYSERR == GNUNET_CONFIGURATION_load(cfg, opt_cfg_filename)))
2165         {
2166           GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
2167                      _("Malformed configuration file `%s', exit ...\n"),
2168                      opt_cfg_filename);
2169           goto shutdown;
2170         }
2171     }
2172   else
2173     {
2174       if (GNUNET_YES == GNUNET_DISK_file_test(cfg_filename))
2175         {
2176           if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load(cfg, cfg_filename))
2177             {
2178               GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
2179                          _("Malformed configuration file `%s', exit ...\n"),
2180                          cfg_filename);
2181               goto shutdown;
2182             }
2183         }
2184       else
2185         {
2186           if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load(cfg, NULL))
2187             {
2188               GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
2189                          _("Malformed configuration, exit ...\n"));
2190               goto shutdown;
2191             }
2192         }
2193     }
2194   if (GNUNET_OK != setup_service(&sh))
2195     goto shutdown;
2196   if ((1 == do_daemonize) && (GNUNET_OK != detach_terminal(&sh)))
2197     {
2198       GNUNET_break(0);
2199       goto shutdown;
2200     }
2201   if (GNUNET_OK != set_user_id(&sh))
2202     goto shutdown;
2203   LOG(GNUNET_ERROR_TYPE_DEBUG,
2204       "Service `%s' runs with configuration from `%s'\n",
2205       service_name,
2206       (NULL != opt_cfg_filename) ? opt_cfg_filename : cfg_filename);
2207   if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(sh.cfg,
2208                                                           "TESTING",
2209                                                           "SKEW_OFFSET",
2210                                                           &skew_offset)) &&
2211       (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(sh.cfg,
2212                                                           "TESTING",
2213                                                           "SKEW_VARIANCE",
2214                                                           &skew_variance)))
2215     {
2216       clock_offset = skew_offset - skew_variance;
2217       GNUNET_TIME_set_offset(clock_offset);
2218       LOG(GNUNET_ERROR_TYPE_DEBUG, "Skewing clock by %dll ms\n", clock_offset);
2219     }
2220   GNUNET_RESOLVER_connect(sh.cfg);
2221
2222   /* actually run service */
2223   err = 0;
2224   GNUNET_SCHEDULER_run(&service_main, &sh);
2225   /* shutdown */
2226   if (1 == do_daemonize)
2227     pid_file_delete(&sh);
2228
2229 shutdown:
2230   if (-1 != sh.ready_confirm_fd)
2231     {
2232       if (1 != write(sh.ready_confirm_fd, err ? "I" : "S", 1))
2233         LOG_STRERROR(GNUNET_ERROR_TYPE_WARNING, "write");
2234       GNUNET_break(0 == close(sh.ready_confirm_fd));
2235     }
2236 #if HAVE_MALLINFO
2237   {
2238     char *counter;
2239
2240     if ((GNUNET_YES == GNUNET_CONFIGURATION_have_value(sh.cfg,
2241                                                        service_name,
2242                                                        "GAUGER_HEAP")) &&
2243         (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(sh.cfg,
2244                                                             service_name,
2245                                                             "GAUGER_HEAP",
2246                                                             &counter)))
2247       {
2248         struct mallinfo mi;
2249
2250         mi = mallinfo();
2251         GAUGER(service_name, counter, mi.usmblks, "blocks");
2252         GNUNET_free(counter);
2253       }
2254   }
2255 #endif
2256   teardown_service(&sh);
2257   GNUNET_free_non_null(sh.handlers);
2258   GNUNET_SPEEDUP_stop_();
2259   GNUNET_CONFIGURATION_destroy(cfg);
2260   GNUNET_free_non_null(logfile);
2261   GNUNET_free_non_null(loglev);
2262   GNUNET_free(cfg_filename);
2263   GNUNET_free_non_null(opt_cfg_filename);
2264
2265   return err ? GNUNET_SYSERR : sh.ret;
2266 }
2267
2268
2269 /**
2270  * Suspend accepting connections from the listen socket temporarily.
2271  * Resume activity using #GNUNET_SERVICE_resume.
2272  *
2273  * @param sh service to stop accepting connections.
2274  */
2275 void
2276 GNUNET_SERVICE_suspend(struct GNUNET_SERVICE_Handle *sh)
2277 {
2278   do_suspend(sh, SUSPEND_STATE_APP);
2279 }
2280
2281
2282 /**
2283  * Resume accepting connections from the listen socket.
2284  *
2285  * @param sh service to resume accepting connections.
2286  */
2287 void
2288 GNUNET_SERVICE_resume(struct GNUNET_SERVICE_Handle *sh)
2289 {
2290   do_resume(sh, SUSPEND_STATE_APP);
2291 }
2292
2293
2294 /**
2295  * Task run to resume receiving data from the client after
2296  * the client called #GNUNET_SERVICE_client_continue().
2297  *
2298  * @param cls our `struct GNUNET_SERVICE_Client`
2299  */
2300 static void
2301 resume_client_receive(void *cls)
2302 {
2303   struct GNUNET_SERVICE_Client *c = cls;
2304   int ret;
2305
2306   c->recv_task = NULL;
2307   /* first, check if there is still something in the buffer */
2308   ret = GNUNET_MST_next(c->mst, GNUNET_YES);
2309   if (GNUNET_SYSERR == ret)
2310     {
2311       if (NULL == c->drop_task)
2312         GNUNET_SERVICE_client_drop(c);
2313       return;
2314     }
2315   if (GNUNET_NO == ret)
2316     return; /* done processing, wait for more later */
2317   GNUNET_assert(GNUNET_OK == ret);
2318   if (GNUNET_YES == c->needs_continue)
2319     return; /* #GNUNET_MST_next() did give a message to the client */
2320   /* need to receive more data from the network first */
2321   if (NULL != c->recv_task)
2322     return;
2323   c->recv_task = GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL,
2324                                                c->sock,
2325                                                &service_client_recv,
2326                                                c);
2327 }
2328
2329
2330 /**
2331  * Continue receiving further messages from the given client.
2332  * Must be called after each message received.
2333  *
2334  * @param c the client to continue receiving from
2335  */
2336 void
2337 GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
2338 {
2339   GNUNET_assert(NULL == c->drop_task);
2340   GNUNET_assert(GNUNET_YES == c->needs_continue);
2341   GNUNET_assert(NULL == c->recv_task);
2342   c->needs_continue = GNUNET_NO;
2343   if (NULL != c->warn_task)
2344     {
2345       GNUNET_SCHEDULER_cancel(c->warn_task);
2346       c->warn_task = NULL;
2347     }
2348   c->recv_task = GNUNET_SCHEDULER_add_now(&resume_client_receive, c);
2349 }
2350
2351
2352 /**
2353  * Disable the warning the server issues if a message is not
2354  * acknowledged in a timely fashion.  Use this call if a client is
2355  * intentionally delayed for a while.  Only applies to the current
2356  * message.
2357  *
2358  * @param c client for which to disable the warning
2359  */
2360 void
2361 GNUNET_SERVICE_client_disable_continue_warning(struct GNUNET_SERVICE_Client *c)
2362 {
2363   GNUNET_break(NULL != c->warn_task);
2364   if (NULL != c->warn_task)
2365     {
2366       GNUNET_SCHEDULER_cancel(c->warn_task);
2367       c->warn_task = NULL;
2368     }
2369 }
2370
2371
2372 /**
2373  * Asynchronously finish dropping the client.
2374  *
2375  * @param cls the `struct GNUNET_SERVICE_Client`.
2376  */
2377 static void
2378 finish_client_drop(void *cls)
2379 {
2380   struct GNUNET_SERVICE_Client *c = cls;
2381   struct GNUNET_SERVICE_Handle *sh = c->sh;
2382
2383   c->drop_task = NULL;
2384   GNUNET_assert(NULL == c->send_task);
2385   GNUNET_assert(NULL == c->recv_task);
2386   GNUNET_assert(NULL == c->warn_task);
2387   GNUNET_MST_destroy(c->mst);
2388   GNUNET_MQ_destroy(c->mq);
2389   if (GNUNET_NO == c->persist)
2390     {
2391       GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(c->sock));
2392       if ((0 != (SUSPEND_STATE_EMFILE & sh->suspend_state)) &&
2393           (0 == (SUSPEND_STATE_SHUTDOWN & sh->suspend_state)))
2394         do_resume(sh, SUSPEND_STATE_EMFILE);
2395     }
2396   else
2397     {
2398       GNUNET_NETWORK_socket_free_memory_only_(c->sock);
2399     }
2400   GNUNET_free(c);
2401   if ((0 != (SUSPEND_STATE_SHUTDOWN & sh->suspend_state)) &&
2402       (GNUNET_NO == have_non_monitor_clients(sh)))
2403     GNUNET_SERVICE_shutdown(sh);
2404 }
2405
2406
2407 /**
2408  * Ask the server to disconnect from the given client.  This is the
2409  * same as returning #GNUNET_SYSERR within the check procedure when
2410  * handling a message, wexcept that it allows dropping of a client even
2411  * when not handling a message from that client.  The `disconnect_cb`
2412  * will be called on @a c even if the application closes the connection
2413  * using this function.
2414  *
2415  * @param c client to disconnect now
2416  */
2417 void
2418 GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
2419 {
2420   struct GNUNET_SERVICE_Handle *sh = c->sh;
2421
2422   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2423              "Client dropped: %p (MQ: %p)\n",
2424              c,
2425              c->mq);
2426 #if EXECINFO
2427   {
2428     void *backtrace_array[MAX_TRACE_DEPTH];
2429     int num_backtrace_strings = backtrace(backtrace_array, MAX_TRACE_DEPTH);
2430     char **backtrace_strings =
2431       backtrace_symbols(backtrace_array, t->num_backtrace_strings);
2432     for (unsigned int i = 0; i < num_backtrace_strings; i++)
2433       LOG(GNUNET_ERROR_TYPE_DEBUG,
2434           "client drop trace %u: %s\n",
2435           i,
2436           backtrace_strings[i]);
2437   }
2438 #endif
2439   if (NULL != c->drop_task)
2440     {
2441       /* asked to drop twice! */
2442       GNUNET_assert(0);
2443       return;
2444     }
2445   GNUNET_CONTAINER_DLL_remove(sh->clients_head, sh->clients_tail, c);
2446   if (NULL != sh->disconnect_cb)
2447     sh->disconnect_cb(sh->cb_cls, c, c->user_context);
2448   if (NULL != c->warn_task)
2449     {
2450       GNUNET_SCHEDULER_cancel(c->warn_task);
2451       c->warn_task = NULL;
2452     }
2453   if (NULL != c->recv_task)
2454     {
2455       GNUNET_SCHEDULER_cancel(c->recv_task);
2456       c->recv_task = NULL;
2457     }
2458   if (NULL != c->send_task)
2459     {
2460       GNUNET_SCHEDULER_cancel(c->send_task);
2461       c->send_task = NULL;
2462     }
2463   c->drop_task = GNUNET_SCHEDULER_add_now(&finish_client_drop, c);
2464 }
2465
2466
2467 /**
2468  * Explicitly stops the service.
2469  *
2470  * @param sh server to shutdown
2471  */
2472 void
2473 GNUNET_SERVICE_shutdown(struct GNUNET_SERVICE_Handle *sh)
2474 {
2475   struct GNUNET_SERVICE_Client *client;
2476
2477   if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN))
2478     do_suspend(sh, SUSPEND_STATE_SHUTDOWN);
2479   while (NULL != (client = sh->clients_head))
2480     GNUNET_SERVICE_client_drop(client);
2481 }
2482
2483
2484 /**
2485  * Set the 'monitor' flag on this client.  Clients which have been
2486  * marked as 'monitors' won't prevent the server from shutting down
2487  * once #GNUNET_SERVICE_stop_listening() has been invoked.  The idea is
2488  * that for "normal" clients we likely want to allow them to process
2489  * their requests; however, monitor-clients are likely to 'never'
2490  * disconnect during shutdown and thus will not be considered when
2491  * determining if the server should continue to exist after
2492  * shutdown has been triggered.
2493  *
2494  * @param c client to mark as a monitor
2495  */
2496 void
2497 GNUNET_SERVICE_client_mark_monitor(struct GNUNET_SERVICE_Client *c)
2498 {
2499   c->is_monitor = GNUNET_YES;
2500   if (((0 != (SUSPEND_STATE_SHUTDOWN & c->sh->suspend_state)) &&
2501        (GNUNET_NO == have_non_monitor_clients(c->sh))))
2502     GNUNET_SERVICE_shutdown(c->sh);
2503 }
2504
2505
2506 /**
2507  * Set the persist option on this client.  Indicates that the
2508  * underlying socket or fd should never really be closed.  Used for
2509  * indicating process death.
2510  *
2511  * @param c client to persist the socket (never to be closed)
2512  */
2513 void
2514 GNUNET_SERVICE_client_persist(struct GNUNET_SERVICE_Client *c)
2515 {
2516   c->persist = GNUNET_YES;
2517 }
2518
2519
2520 /**
2521  * Obtain the message queue of @a c.  Convenience function.
2522  *
2523  * @param c the client to continue receiving from
2524  * @return the message queue of @a c
2525  */
2526 struct GNUNET_MQ_Handle *
2527 GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c)
2528 {
2529   return c->mq;
2530 }
2531
2532
2533 /* end of service_new.c */