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