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