ddbae441098a577cc4becde995a5e56bc8c14f32
[oweals/gnunet.git] / src / util / server.c
1 /*
2      This file is part of GNUnet.
3      (C) 2009 Christian Grothoff (and other contributing authors)
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 2, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21 /**
22  * @file util/server.c
23  * @brief library for building GNUnet network servers
24  * @author Christian Grothoff
25  */
26
27 #include "platform.h"
28 #include "gnunet_common.h"
29 #include "gnunet_connection_lib.h"
30 #include "gnunet_scheduler_lib.h"
31 #include "gnunet_server_lib.h"
32 #include "gnunet_time_lib.h"
33 #include "gnunet_disk_lib.h"
34 #include "gnunet_protocols.h"
35
36 #define DEBUG_SERVER GNUNET_NO
37
38 /**
39  * List of arrays of message handlers.
40  */
41 struct HandlerList
42 {
43   /**
44    * This is a linked list.
45    */
46   struct HandlerList *next;
47
48   /**
49    * NULL-terminated array of handlers.
50    */
51   const struct GNUNET_SERVER_MessageHandler *handlers;
52 };
53
54
55 /**
56  * List of arrays of message handlers.
57  */
58 struct NotifyList
59 {
60   /**
61    * This is a linked list.
62    */
63   struct NotifyList *next;
64
65   /**
66    * Function to call.
67    */
68   GNUNET_SERVER_DisconnectCallback callback;
69
70   /**
71    * Closure for callback.
72    */
73   void *callback_cls;
74 };
75
76
77 /**
78  * @brief handle for a server
79  */
80 struct GNUNET_SERVER_Handle
81 {
82   /**
83    * List of handlers for incoming messages.
84    */
85   struct HandlerList *handlers;
86
87   /**
88    * List of our current clients.
89    */
90   struct GNUNET_SERVER_Client *clients;
91
92   /**
93    * Linked list of functions to call on disconnects by clients.
94    */
95   struct NotifyList *disconnect_notify_list;
96
97   /**
98    * Function to call for access control.
99    */
100   GNUNET_CONNECTION_AccessCheck access;
101
102   /**
103    * Closure for access.
104    */
105   void *access_cls;
106
107   /**
108    * NULL-terminated array of sockets used to listen for new
109    * connections.
110    */
111   struct GNUNET_NETWORK_Handle **listen_sockets;
112
113   /**
114    * After how long should an idle connection time
115    * out (on write).
116    */
117   struct GNUNET_TIME_Relative idle_timeout;
118
119   /**
120    * Task scheduled to do the listening.
121    */
122   GNUNET_SCHEDULER_TaskIdentifier listen_task;
123
124   /**
125    * Do we ignore messages of types that we do not understand or do we
126    * require that a handler is found (and if not kill the connection)?
127    */
128   int require_found;
129
130   /**
131    * Should all of the clients of this server continue to process
132    * connections as usual even if we get a shutdown request? (the
133    * listen socket always ignores shutdown).
134    */
135   int clients_ignore_shutdown;
136
137 };
138
139
140 /**
141  * @brief handle for a client of the server
142  */
143 struct GNUNET_SERVER_Client
144 {
145
146   /**
147    * This is a linked list.
148    */
149   struct GNUNET_SERVER_Client *next;
150
151   /**
152    * Processing of incoming data.
153    */
154   struct GNUNET_SERVER_MessageStreamTokenizer *mst;
155
156   /**
157    * Server that this client belongs to.
158    */
159   struct GNUNET_SERVER_Handle *server;
160
161   /**
162    * Client closure for callbacks.
163    */
164   struct GNUNET_CONNECTION_Handle *connection;
165
166   /**
167    * ID of task used to restart processing.
168    */
169   GNUNET_SCHEDULER_TaskIdentifier restart_task;
170
171   /**
172    * Task that warns about missing calls to 'GNUNET_SERVER_receive_done'.
173    */
174   GNUNET_SCHEDULER_TaskIdentifier warn_task;
175
176   /**
177    * Time when the warn task was started.
178    */
179   struct GNUNET_TIME_Absolute warn_start;
180
181   /**
182    * Last activity on this socket (used to time it out
183    * if reference_count == 0).
184    */
185   struct GNUNET_TIME_Absolute last_activity;
186
187   /**
188    *
189    */
190   GNUNET_CONNECTION_TransmitReadyNotify callback;
191
192   /**
193    * callback
194    */
195   void *callback_cls;
196
197   /**
198    * After how long should an idle connection time
199    * out (on write).
200    */
201   struct GNUNET_TIME_Relative idle_timeout;
202
203   /**
204    * Number of external entities with a reference to
205    * this client object.
206    */
207   unsigned int reference_count;
208
209   /**
210    * Was processing if incoming messages suspended while
211    * we were still processing data already received?
212    * This is a counter saying how often processing was
213    * suspended (once per handler invoked).
214    */
215   unsigned int suspended;
216
217   /**
218    * Are we currently in the "process_client_buffer" function (and
219    * will hence restart the receive job on exit if suspended == 0 once
220    * we are done?).  If this is set, then "receive_done" will
221    * essentially only decrement suspended; if this is not set, then
222    * "receive_done" may need to restart the receive process (either
223    * from the side-buffer or via select/recv).
224    */
225   int in_process_client_buffer;
226
227   /**
228    * We're about to close down this client due to some serious
229    * error.
230    */
231   int shutdown_now;
232
233   /**
234    * Are we currently trying to receive? (YES if we are, NO if we are not,
235    * SYSERR if data is already available in MST).
236    */
237   int receive_pending;
238
239   /**
240    * Persist the file handle for this client no matter what happens,
241    * force the OS to close once the process actually dies.  Should only
242    * be used in special cases!
243    */
244   int persist;
245
246   /**
247    * Type of last message processed (for warn_no_receive_done).
248    */
249   uint16_t warn_type;
250
251   /**
252    * unique identifier to distinguish between clients
253    */
254   uint64_t id;
255 };
256
257
258 /**
259  * Scheduler says our listen socket is ready.  Process it!
260  *
261  * @param cls handle to our server for which we are processing the listen
262  *        socket
263  * @param tc reason why we are running right now
264  */
265 static void
266 process_listen_socket (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
267 {
268   struct GNUNET_SERVER_Handle *server = cls;
269   struct GNUNET_CONNECTION_Handle *sock;
270   struct GNUNET_SERVER_Client *client;
271   struct GNUNET_NETWORK_FDSet *r;
272   unsigned int i;
273
274   server->listen_task = GNUNET_SCHEDULER_NO_TASK;
275   r = GNUNET_NETWORK_fdset_create ();
276   i = 0;
277   while (NULL != server->listen_sockets[i])
278     GNUNET_NETWORK_fdset_set (r, server->listen_sockets[i++]);
279   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
280   {
281     /* ignore shutdown, someone else will take care of it! */
282     server->listen_task =
283         GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH,
284                                      GNUNET_SCHEDULER_NO_TASK,
285                                      GNUNET_TIME_UNIT_FOREVER_REL, r, NULL,
286                                      &process_listen_socket, server);
287     GNUNET_NETWORK_fdset_destroy (r);
288     return;
289   }
290   i = 0;
291   while (NULL != server->listen_sockets[i])
292   {
293     if (GNUNET_NETWORK_fdset_isset (tc->read_ready, server->listen_sockets[i]))
294     {
295       sock =
296           GNUNET_CONNECTION_create_from_accept (server->access,
297                                                 server->access_cls,
298                                                 server->listen_sockets[i]);
299       if (sock != NULL)
300       {
301 #if DEBUG_SERVER
302         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
303                     "Server accepted incoming connection.\n");
304 #endif
305         client = GNUNET_SERVER_connect_socket (server, sock);
306         GNUNET_CONNECTION_ignore_shutdown (sock,
307                                            server->clients_ignore_shutdown);
308         /* decrement reference count, we don't keep "client" alive */
309         GNUNET_SERVER_client_drop (client);
310       }
311     }
312     i++;
313   }
314   /* listen for more! */
315   server->listen_task =
316       GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH,
317                                    GNUNET_SCHEDULER_NO_TASK,
318                                    GNUNET_TIME_UNIT_FOREVER_REL, r, NULL,
319                                    &process_listen_socket, server);
320   GNUNET_NETWORK_fdset_destroy (r);
321 }
322
323
324 /**
325  * Create and initialize a listen socket for the server.
326  *
327  * @param serverAddr address to listen on
328  * @param socklen length of address
329  * @return NULL on error, otherwise the listen socket
330  */
331 static struct GNUNET_NETWORK_Handle *
332 open_listen_socket (const struct sockaddr *serverAddr, socklen_t socklen)
333 {
334   const static int on = 1;
335   struct GNUNET_NETWORK_Handle *sock;
336   uint16_t port;
337   int eno;
338
339   switch (serverAddr->sa_family)
340   {
341   case AF_INET:
342     port = ntohs (((const struct sockaddr_in *) serverAddr)->sin_port);
343     break;
344   case AF_INET6:
345     port = ntohs (((const struct sockaddr_in6 *) serverAddr)->sin6_port);
346     break;
347   case AF_UNIX:
348     port = 0;
349     break;
350   default:
351     GNUNET_break (0);
352     port = 0;
353     break;
354   }
355   sock = GNUNET_NETWORK_socket_create (serverAddr->sa_family, SOCK_STREAM, 0);
356   if (NULL == sock)
357   {
358     GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket");
359     errno = 0;
360     return NULL;
361   }
362   if (port != 0)
363   {
364     if (GNUNET_NETWORK_socket_setsockopt
365         (sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) != GNUNET_OK)
366       GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
367                            "setsockopt");
368 #ifdef IPV6_V6ONLY
369     if ((serverAddr->sa_family == AF_INET6) &&
370         (GNUNET_NETWORK_socket_setsockopt
371          (sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on)) != GNUNET_OK))
372       GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
373                            "setsockopt");
374 #endif
375   }
376   /* bind the socket */
377   if (GNUNET_NETWORK_socket_bind (sock, serverAddr, socklen) != GNUNET_OK)
378   {
379     eno = errno;
380     if (errno != EADDRINUSE)
381     {
382       /* we don't log 'EADDRINUSE' here since an IPv4 bind may
383        * fail if we already took the port on IPv6; if both IPv4 and
384        * IPv6 binds fail, then our caller will log using the
385        * errno preserved in 'eno' */
386       GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind");
387       if (port != 0)
388         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
389                     _("`%s' failed for port %d (%s).\n"), "bind", port,
390                     (serverAddr->sa_family == AF_INET) ? "IPv4" : "IPv6");
391       eno = 0;
392     }
393     else
394     {
395       if (port != 0)
396         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
397                     _("`%s' failed for port %d (%s): address already in use\n"),
398                     "bind", port,
399                     (serverAddr->sa_family == AF_INET) ? "IPv4" : "IPv6");
400       else if (serverAddr->sa_family == AF_UNIX)
401         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
402                     _("`%s' failed for `%s': address already in use\n"), "bind",
403                     ((const struct sockaddr_un *) serverAddr)->sun_path);
404
405     }
406     GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
407     errno = eno;
408     return NULL;
409   }
410   if (GNUNET_OK != GNUNET_NETWORK_socket_listen (sock, 5))
411   {
412     GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "listen");
413     GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
414     errno = 0;
415     return NULL;
416   }
417 #if DEBUG_SERVER
418   if (port != 0)
419     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
420                 "Server starts to listen on port %u.\n", port);
421 #endif
422   return sock;
423 }
424
425
426 /**
427  * Create a new server.
428  *
429  * @param access function for access control
430  * @param access_cls closure for access
431  * @param lsocks NULL-terminated array of listen sockets
432  * @param idle_timeout after how long should we timeout idle connections?
433  * @param require_found if YES, connections sending messages of unknown type
434  *        will be closed
435  * @return handle for the new server, NULL on error
436  *         (typically, "port" already in use)
437  */
438 struct GNUNET_SERVER_Handle *
439 GNUNET_SERVER_create_with_sockets (GNUNET_CONNECTION_AccessCheck access,
440                                    void *access_cls,
441                                    struct GNUNET_NETWORK_Handle **lsocks,
442                                    struct GNUNET_TIME_Relative idle_timeout,
443                                    int require_found)
444 {
445   struct GNUNET_SERVER_Handle *ret;
446   struct GNUNET_NETWORK_FDSet *r;
447   int i;
448
449   ret = GNUNET_malloc (sizeof (struct GNUNET_SERVER_Handle));
450   ret->idle_timeout = idle_timeout;
451   ret->listen_sockets = lsocks;
452   ret->access = access;
453   ret->access_cls = access_cls;
454   ret->require_found = require_found;
455   if (lsocks != NULL)
456   {
457     r = GNUNET_NETWORK_fdset_create ();
458     i = 0;
459     while (NULL != ret->listen_sockets[i])
460       GNUNET_NETWORK_fdset_set (r, ret->listen_sockets[i++]);
461     ret->listen_task =
462         GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH,
463                                      GNUNET_SCHEDULER_NO_TASK,
464                                      GNUNET_TIME_UNIT_FOREVER_REL, r, NULL,
465                                      &process_listen_socket, ret);
466     GNUNET_NETWORK_fdset_destroy (r);
467   }
468   return ret;
469 }
470
471
472 /**
473  * Create a new server.
474  *
475  * @param access function for access control
476  * @param access_cls closure for access
477  * @param serverAddr address to listen on (including port), NULL terminated array
478  * @param socklen length of serverAddr
479  * @param idle_timeout after how long should we timeout idle connections?
480  * @param require_found if YES, connections sending messages of unknown type
481  *        will be closed
482  * @return handle for the new server, NULL on error
483  *         (typically, "port" already in use)
484  */
485 struct GNUNET_SERVER_Handle *
486 GNUNET_SERVER_create (GNUNET_CONNECTION_AccessCheck access, void *access_cls,
487                       struct sockaddr *const *serverAddr,
488                       const socklen_t * socklen,
489                       struct GNUNET_TIME_Relative idle_timeout,
490                       int require_found)
491 {
492   struct GNUNET_NETWORK_Handle **lsocks;
493   unsigned int i;
494   unsigned int j;
495
496   i = 0;
497   while (serverAddr[i] != NULL)
498     i++;
499   if (i > 0)
500   {
501     lsocks = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (i + 1));
502     i = 0;
503     j = 0;
504     while (serverAddr[i] != NULL)
505     {
506       lsocks[j] = open_listen_socket (serverAddr[i], socklen[i]);
507       if (lsocks[j] != NULL)
508         j++;
509       i++;
510     }
511     if (j == 0)
512     {
513       if (errno != 0)
514         GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind");
515       GNUNET_free (lsocks);
516       lsocks = NULL;
517     }
518   }
519   else
520   {
521     lsocks = NULL;
522   }
523   return GNUNET_SERVER_create_with_sockets (access, access_cls, lsocks,
524                                             idle_timeout, require_found);
525 }
526
527
528 /**
529  * Free resources held by this server.
530  *
531  * @param s server to destroy
532  */
533 void
534 GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *s)
535 {
536   struct HandlerList *hpos;
537   struct NotifyList *npos;
538   unsigned int i;
539
540 #if DEBUG_SERVER
541   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Server shutting down.\n");
542 #endif
543   if (GNUNET_SCHEDULER_NO_TASK != s->listen_task)
544   {
545     GNUNET_SCHEDULER_cancel (s->listen_task);
546     s->listen_task = GNUNET_SCHEDULER_NO_TASK;
547   }
548   if (s->listen_sockets != NULL)
549   {
550     i = 0;
551     while (s->listen_sockets[i] != NULL)
552       GNUNET_break (GNUNET_OK ==
553                     GNUNET_NETWORK_socket_close (s->listen_sockets[i++]));
554     GNUNET_free (s->listen_sockets);
555     s->listen_sockets = NULL;
556   }
557   while (s->clients != NULL)
558     GNUNET_SERVER_client_disconnect (s->clients);
559   while (NULL != (hpos = s->handlers))
560   {
561     s->handlers = hpos->next;
562     GNUNET_free (hpos);
563   }
564   while (NULL != (npos = s->disconnect_notify_list))
565   {
566     npos->callback (npos->callback_cls, NULL);
567     s->disconnect_notify_list = npos->next;
568     GNUNET_free (npos);
569   }
570   GNUNET_free (s);
571 }
572
573
574 /**
575  * Add additional handlers to an existing server.
576  *
577  * @param server the server to add handlers to
578  * @param handlers array of message handlers for
579  *        incoming messages; the last entry must
580  *        have "NULL" for the "callback"; multiple
581  *        entries for the same type are allowed,
582  *        they will be called in order of occurence.
583  *        These handlers can be removed later;
584  *        the handlers array must exist until removed
585  *        (or server is destroyed).
586  */
587 void
588 GNUNET_SERVER_add_handlers (struct GNUNET_SERVER_Handle *server,
589                             const struct GNUNET_SERVER_MessageHandler *handlers)
590 {
591   struct HandlerList *p;
592
593   p = GNUNET_malloc (sizeof (struct HandlerList));
594   p->handlers = handlers;
595   p->next = server->handlers;
596   server->handlers = p;
597 }
598
599
600 /**
601  * Task run to warn about missing calls to 'GNUNET_SERVER_receive_done'.
602  *
603  * @param cls our 'struct GNUNET_SERVER_Client*' to process more requests from
604  * @param tc scheduler context (unused)
605  */
606 static void
607 warn_no_receive_done (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
608 {
609   struct GNUNET_SERVER_Client *client = cls;
610
611   client->warn_task =
612       GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
613                                     &warn_no_receive_done, client);
614   if (0 == (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
615     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
616                 _
617                 ("Processing code for message of type %u did not call GNUNET_SERVER_receive_done after %llums\n"),
618                 (unsigned int) client->warn_type,
619                 (unsigned long long)
620                 GNUNET_TIME_absolute_get_duration
621                 (client->warn_start).rel_value);
622 }
623
624
625 /**
626  * Disable the warning the server issues if a message is not acknowledged
627  * in a timely fashion.  Use this call if a client is intentionally delayed
628  * for a while.  Only applies to the current message.
629  *
630  * @param client client for which to disable the warning
631  */
632 void
633 GNUNET_SERVER_disable_receive_done_warning (struct GNUNET_SERVER_Client *client)
634 {
635   if (GNUNET_SCHEDULER_NO_TASK != client->warn_task)
636   {
637     GNUNET_SCHEDULER_cancel (client->warn_task);
638     client->warn_task = GNUNET_SCHEDULER_NO_TASK;
639   }
640 }
641
642
643 /**
644  * Inject a message into the server, pretend it came
645  * from the specified client.  Delivery of the message
646  * will happen instantly (if a handler is installed;
647  * otherwise the call does nothing).
648  *
649  * @param server the server receiving the message
650  * @param sender the "pretended" sender of the message
651  *        can be NULL!
652  * @param message message to transmit
653  * @return GNUNET_OK if the message was OK and the
654  *                   connection can stay open
655  *         GNUNET_SYSERR if the connection to the
656  *         client should be shut down
657  */
658 int
659 GNUNET_SERVER_inject (struct GNUNET_SERVER_Handle *server,
660                       struct GNUNET_SERVER_Client *sender,
661                       const struct GNUNET_MessageHeader *message)
662 {
663   struct HandlerList *pos;
664   const struct GNUNET_SERVER_MessageHandler *mh;
665   unsigned int i;
666   uint16_t type;
667   uint16_t size;
668   int found;
669
670   type = ntohs (message->type);
671   size = ntohs (message->size);
672 #if DEBUG_SERVER
673
674   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
675               "Server schedules transmission of %u-byte message of type %u to client.\n",
676               size, type);
677 #endif
678   pos = server->handlers;
679   found = GNUNET_NO;
680   while (pos != NULL)
681   {
682     i = 0;
683     while (pos->handlers[i].callback != NULL)
684     {
685       mh = &pos->handlers[i];
686       if ((mh->type == type) || (mh->type == GNUNET_MESSAGE_TYPE_ALL))
687       {
688         if ((mh->expected_size != 0) && (mh->expected_size != size))
689         {
690 #if GNUNET8_NETWORK_IS_DEAD
691           GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
692                       "Expected %u bytes for message of type %u, got %u\n",
693                       mh->expected_size, mh->type, size);
694           GNUNET_break_op (0);
695 #endif
696           return GNUNET_SYSERR;
697         }
698         if (sender != NULL)
699         {
700           if (0 == sender->suspended)
701           {
702             sender->warn_start = GNUNET_TIME_absolute_get ();
703             sender->warn_task =
704                 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
705                                               &warn_no_receive_done, sender);
706             sender->warn_type = type;
707           }
708           sender->suspended++;
709         }
710         mh->callback (mh->callback_cls, sender, message);
711         found = GNUNET_YES;
712       }
713       i++;
714     }
715     pos = pos->next;
716   }
717   if (found == GNUNET_NO)
718   {
719     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
720                 "Received message of unknown type %d\n", type);
721     if (server->require_found == GNUNET_YES)
722       return GNUNET_SYSERR;
723   }
724   return GNUNET_OK;
725 }
726
727
728 /**
729  * We are receiving an incoming message.  Process it.
730  *
731  * @param cls our closure (handle for the client)
732  * @param buf buffer with data received from network
733  * @param available number of bytes available in buf
734  * @param addr address of the sender
735  * @param addrlen length of addr
736  * @param errCode code indicating errors receiving, 0 for success
737  */
738 static void
739 process_incoming (void *cls, const void *buf, size_t available,
740                   const struct sockaddr *addr, socklen_t addrlen, int errCode);
741
742
743 /**
744  * Process messages from the client's message tokenizer until either
745  * the tokenizer is empty (and then schedule receiving more), or 
746  * until some handler is not immediately done (then wait for restart_processing)
747  * or shutdown.
748  *
749  * @param client the client to process, RC must have already been increased
750  *        using GNUNET_SERVER_client_keep and will be decreased by one in this
751  *        function
752  * @param ret GNUNET_NO to start processing from the buffer,
753  *            GNUNET_OK if the mst buffer is drained and we should instantly go back to receiving
754  *            GNUNET_SYSERR if we should instantly abort due to error in a previous step
755  */
756 static void
757 process_mst (struct GNUNET_SERVER_Client *client, int ret)
758 {
759   while ((ret != GNUNET_SYSERR) && (client->server != NULL) &&
760          (GNUNET_YES != client->shutdown_now) && (0 == client->suspended))
761   {
762     if (ret == GNUNET_OK)
763     {
764       client->receive_pending = GNUNET_YES;
765 #if DEBUG_SERVER
766       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
767                   "Server re-enters receive loop, timeout: %llu.\n",
768                   client->idle_timeout.rel_value);
769 #endif
770       GNUNET_CONNECTION_receive (client->connection,
771                                  GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
772                                  client->idle_timeout, &process_incoming,
773                                  client);
774       break;
775     }
776 #if DEBUG_SERVER
777     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
778                 "Server processes additional messages instantly.\n");
779 #endif
780     ret =
781         GNUNET_SERVER_mst_receive (client->mst, client, NULL, 0, GNUNET_NO,
782                                    GNUNET_YES);
783   }
784 #if DEBUG_SERVER
785   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
786               "Server leaves instant processing loop: ret = %d, server = %p, shutdown = %d, suspended = %u\n",
787               ret, client->server, client->shutdown_now, client->suspended);
788 #endif
789
790   if (ret == GNUNET_NO)
791   {
792 #if DEBUG_SERVER
793     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
794                 "Server has more data pending but is suspended.\n");
795 #endif
796     client->receive_pending = GNUNET_SYSERR;    /* data pending */
797   }
798   if ((ret == GNUNET_SYSERR) || (GNUNET_YES == client->shutdown_now))
799     GNUNET_SERVER_client_disconnect (client);
800   GNUNET_SERVER_client_drop (client);
801 }
802
803
804 /**
805  * We are receiving an incoming message.  Process it.
806  *
807  * @param cls our closure (handle for the client)
808  * @param buf buffer with data received from network
809  * @param available number of bytes available in buf
810  * @param addr address of the sender
811  * @param addrlen length of addr
812  * @param errCode code indicating errors receiving, 0 for success
813  */
814 static void
815 process_incoming (void *cls, const void *buf, size_t available,
816                   const struct sockaddr *addr, socklen_t addrlen, int errCode)
817 {
818   struct GNUNET_SERVER_Client *client = cls;
819   struct GNUNET_SERVER_Handle *server = client->server;
820   struct GNUNET_TIME_Absolute end;
821   struct GNUNET_TIME_Absolute now;
822   int ret;
823
824   GNUNET_assert (client->receive_pending == GNUNET_YES);
825   client->receive_pending = GNUNET_NO;
826   now = GNUNET_TIME_absolute_get ();
827   end = GNUNET_TIME_absolute_add (client->last_activity, client->idle_timeout);
828
829   if ((buf == NULL) && (available == 0) && (addr == NULL) && (errCode == 0) &&
830       (client->shutdown_now != GNUNET_YES) && (server != NULL) &&
831       (GNUNET_YES == GNUNET_CONNECTION_check (client->connection)) &&
832       (end.abs_value > now.abs_value))
833   {
834     /* wait longer, timeout changed (i.e. due to us sending) */
835 #if DEBUG_SERVER
836     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
837                 "Receive time out, but no disconnect due to sending (%p)\n",
838                 GNUNET_a2s (addr, addrlen));
839 #endif
840     client->receive_pending = GNUNET_YES;
841     GNUNET_CONNECTION_receive (client->connection,
842                                GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
843                                GNUNET_TIME_absolute_get_remaining (end),
844                                &process_incoming, client);
845     return;
846   }
847   if ((buf == NULL) || (available == 0) || (errCode != 0) || (server == NULL) ||
848       (client->shutdown_now == GNUNET_YES) ||
849       (GNUNET_YES != GNUNET_CONNECTION_check (client->connection)))
850   {
851     /* other side closed connection, error connecting, etc. */
852     GNUNET_SERVER_client_disconnect (client);
853     return;
854   }
855 #if DEBUG_SERVER
856   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Server receives %u bytes from `%s'.\n",
857               (unsigned int) available, GNUNET_a2s (addr, addrlen));
858 #endif
859   GNUNET_SERVER_client_keep (client);
860   client->last_activity = now;
861   ret =
862       GNUNET_SERVER_mst_receive (client->mst, client, buf, available, GNUNET_NO,
863                                  GNUNET_YES);
864   process_mst (client, ret);
865 }
866
867
868 /**
869  * Task run to start again receiving from the network
870  * and process requests.
871  *
872  * @param cls our 'struct GNUNET_SERVER_Client*' to process more requests from
873  * @param tc scheduler context (unused)
874  */
875 static void
876 restart_processing (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
877 {
878   struct GNUNET_SERVER_Client *client = cls;
879   struct GNUNET_SERVER_Handle *server = client->server;
880
881   client->restart_task = GNUNET_SCHEDULER_NO_TASK;
882   if ((0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) &&
883       (GNUNET_NO == server->clients_ignore_shutdown))
884   {
885     GNUNET_SERVER_client_disconnect (client);
886     return;
887   }
888   if (client->receive_pending == GNUNET_NO)
889   {
890 #if DEBUG_SERVER
891     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
892                 "Server begins to read again from client.\n");
893 #endif
894     client->receive_pending = GNUNET_YES;
895     GNUNET_CONNECTION_receive (client->connection,
896                                GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
897                                client->idle_timeout, &process_incoming, client);
898     return;
899   }
900 #if DEBUG_SERVER
901   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
902               "Server continues processing messages still in the buffer.\n");
903 #endif
904   GNUNET_SERVER_client_keep (client);
905   client->receive_pending = GNUNET_NO;
906   process_mst (client, GNUNET_NO);
907 }
908
909
910 /**
911  * This function is called whenever our inbound message tokenizer has
912  * received a complete message.
913  *
914  * @param cls closure (struct GNUNET_SERVER_Handle)
915  * @param client identification of the client (struct GNUNET_SERVER_Client*)
916  * @param message the actual message
917  */
918 static void
919 client_message_tokenizer_callback (void *cls, void *client,
920                                    const struct GNUNET_MessageHeader *message)
921 {
922   struct GNUNET_SERVER_Handle *server = cls;
923   struct GNUNET_SERVER_Client *sender = client;
924   int ret;
925
926 #if DEBUG_SERVER
927
928   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
929               "Tokenizer gives server message of type %u from client\n",
930               ntohs (message->type));
931 #endif
932   sender->in_process_client_buffer = GNUNET_YES;
933   ret = GNUNET_SERVER_inject (server, sender, message);
934   sender->in_process_client_buffer = GNUNET_NO;
935   if (GNUNET_OK != ret)
936     GNUNET_SERVER_client_disconnect (sender);
937 }
938
939
940 /**
941  * Get a unique identifier for each GNUNET_SERVER_Client
942  */
943 static uint64_t
944 get_client_id (void)
945 {
946   static uint64_t id;
947
948   GNUNET_assert (id < ULONG_LONG_MAX);
949   return (id++);
950 }
951
952 /**
953  * Add a TCP socket-based connection to the set of handles managed by
954  * this server.  Use this function for outgoing (P2P) connections that
955  * we initiated (and where this server should process incoming
956  * messages).
957  *
958  * @param server the server to use
959  * @param connection the connection to manage (client must
960  *        stop using this connection from now on)
961  * @return the client handle (client should call
962  *         "client_drop" on the return value eventually)
963  */
964 struct GNUNET_SERVER_Client *
965 GNUNET_SERVER_connect_socket (struct GNUNET_SERVER_Handle *server,
966                               struct GNUNET_CONNECTION_Handle *connection)
967 {
968   struct GNUNET_SERVER_Client *client;
969
970   client = GNUNET_malloc (sizeof (struct GNUNET_SERVER_Client));
971   client->connection = connection;
972   client->mst =
973       GNUNET_SERVER_mst_create (&client_message_tokenizer_callback, server);
974   client->reference_count = 1;
975   client->server = server;
976   client->last_activity = GNUNET_TIME_absolute_get ();
977   client->next = server->clients;
978   client->idle_timeout = server->idle_timeout;
979   server->clients = client;
980   client->receive_pending = GNUNET_YES;
981   client->callback = NULL;
982   client->callback_cls = NULL;
983   client->id = get_client_id ();
984   GNUNET_CONNECTION_receive (client->connection,
985                              GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
986                              client->idle_timeout, &process_incoming, client);
987   return client;
988 }
989
990
991 /**
992  * Change the timeout for a particular client.  Decreasing the timeout
993  * may not go into effect immediately (only after the previous timeout
994  * times out or activity happens on the socket).
995  *
996  * @param client the client to update
997  * @param timeout new timeout for activities on the socket
998  */
999 void
1000 GNUNET_SERVER_client_set_timeout (struct GNUNET_SERVER_Client *client,
1001                                   struct GNUNET_TIME_Relative timeout)
1002 {
1003   client->idle_timeout = timeout;
1004 }
1005
1006
1007 /**
1008  * Notify the server that the given client handle should
1009  * be kept (keeps the connection up if possible, increments
1010  * the internal reference counter).
1011  *
1012  * @param client the client to keep
1013  */
1014 void
1015 GNUNET_SERVER_client_keep (struct GNUNET_SERVER_Client *client)
1016 {
1017   client->reference_count++;
1018 }
1019
1020
1021 /**
1022  * Notify the server that the given client handle is no
1023  * longer required.  Decrements the reference counter.  If
1024  * that counter reaches zero an inactive connection maybe
1025  * closed.
1026  *
1027  * @param client the client to drop
1028  */
1029 void
1030 GNUNET_SERVER_client_drop (struct GNUNET_SERVER_Client *client)
1031 {
1032   GNUNET_assert (client->reference_count > 0);
1033   client->reference_count--;
1034   if ((client->shutdown_now == GNUNET_YES) && (client->reference_count == 0))
1035     GNUNET_SERVER_client_disconnect (client);
1036 }
1037
1038
1039 /**
1040  * Obtain the network address of the other party.
1041  *
1042  * @param client the client to get the address for
1043  * @param addr where to store the address
1044  * @param addrlen where to store the length of the address
1045  * @return GNUNET_OK on success
1046  */
1047 int
1048 GNUNET_SERVER_client_get_address (struct GNUNET_SERVER_Client *client,
1049                                   void **addr, size_t * addrlen)
1050 {
1051   return GNUNET_CONNECTION_get_address (client->connection, addr, addrlen);
1052 }
1053
1054
1055 /**
1056  * Ask the server to notify us whenever a client disconnects.
1057  * This function is called whenever the actual network connection
1058  * is closed; the reference count may be zero or larger than zero
1059  * at this point.
1060  *
1061  * @param server the server manageing the clients
1062  * @param callback function to call on disconnect
1063  * @param callback_cls closure for callback
1064  */
1065 void
1066 GNUNET_SERVER_disconnect_notify (struct GNUNET_SERVER_Handle *server,
1067                                  GNUNET_SERVER_DisconnectCallback callback,
1068                                  void *callback_cls)
1069 {
1070   struct NotifyList *n;
1071
1072   n = GNUNET_malloc (sizeof (struct NotifyList));
1073   n->callback = callback;
1074   n->callback_cls = callback_cls;
1075   n->next = server->disconnect_notify_list;
1076   server->disconnect_notify_list = n;
1077 }
1078
1079
1080 /**
1081  * Ask the server to stop notifying us whenever a client disconnects.
1082  *
1083  * @param server the server manageing the clients
1084  * @param callback function to call on disconnect
1085  * @param callback_cls closure for callback
1086  */
1087 void
1088 GNUNET_SERVER_disconnect_notify_cancel (struct GNUNET_SERVER_Handle *server,
1089                                         GNUNET_SERVER_DisconnectCallback
1090                                         callback, void *callback_cls)
1091 {
1092   struct NotifyList *pos;
1093   struct NotifyList *prev;
1094
1095   prev = NULL;
1096   pos = server->disconnect_notify_list;
1097   while (pos != NULL)
1098   {
1099     if ((pos->callback == callback) && (pos->callback_cls == callback_cls))
1100       break;
1101     prev = pos;
1102     pos = pos->next;
1103   }
1104   if (pos == NULL)
1105   {
1106     GNUNET_break (0);
1107     return;
1108   }
1109   if (prev == NULL)
1110     server->disconnect_notify_list = pos->next;
1111   else
1112     prev->next = pos->next;
1113   GNUNET_free (pos);
1114 }
1115
1116
1117 /**
1118  * Ask the server to disconnect from the given client.
1119  * This is the same as returning GNUNET_SYSERR from a message
1120  * handler, except that it allows dropping of a client even
1121  * when not handling a message from that client.
1122  *
1123  * @param client the client to disconnect from
1124  */
1125 void
1126 GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client)
1127 {
1128   struct GNUNET_SERVER_Client *prev;
1129   struct GNUNET_SERVER_Client *pos;
1130   struct GNUNET_SERVER_Handle *server;
1131   struct NotifyList *n;
1132   unsigned int rc;
1133
1134 #if DEBUG_SERVER
1135   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1136               "Client is being disconnected from the server.\n");
1137 #endif
1138   if (client->restart_task != GNUNET_SCHEDULER_NO_TASK)
1139   {
1140     GNUNET_SCHEDULER_cancel (client->restart_task);
1141     client->restart_task = GNUNET_SCHEDULER_NO_TASK;
1142   }
1143   if (client->warn_task != GNUNET_SCHEDULER_NO_TASK)
1144   {
1145     GNUNET_SCHEDULER_cancel (client->warn_task);
1146     client->warn_task = GNUNET_SCHEDULER_NO_TASK;
1147   }
1148   if (GNUNET_YES == client->receive_pending)
1149   {
1150     GNUNET_CONNECTION_receive_cancel (client->connection);
1151     client->receive_pending = GNUNET_NO;
1152   }
1153
1154   rc = client->reference_count;
1155   if (client->server != NULL)
1156   {
1157     server = client->server;
1158     client->server = NULL;
1159     client->shutdown_now = GNUNET_YES;
1160     prev = NULL;
1161     pos = server->clients;
1162     while ((pos != NULL) && (pos != client))
1163     {
1164       prev = pos;
1165       pos = pos->next;
1166     }
1167     GNUNET_assert (pos != NULL);
1168     if (prev == NULL)
1169       server->clients = pos->next;
1170     else
1171       prev->next = pos->next;
1172     if (client->restart_task != GNUNET_SCHEDULER_NO_TASK)
1173     {
1174       GNUNET_SCHEDULER_cancel (client->restart_task);
1175       client->restart_task = GNUNET_SCHEDULER_NO_TASK;
1176     }
1177     if (client->warn_task != GNUNET_SCHEDULER_NO_TASK)
1178     {
1179       GNUNET_SCHEDULER_cancel (client->warn_task);
1180       client->warn_task = GNUNET_SCHEDULER_NO_TASK;
1181     }
1182     n = server->disconnect_notify_list;
1183     while (n != NULL)
1184     {
1185       n->callback (n->callback_cls, client);
1186       n = n->next;
1187     }
1188   }
1189   if (rc > 0)
1190   {
1191 #if DEBUG_SERVER
1192     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1193                 "RC still positive, not destroying everything.\n");
1194 #endif
1195     return;
1196   }
1197   if (client->in_process_client_buffer == GNUNET_YES)
1198   {
1199 #if DEBUG_SERVER
1200     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1201                 "Still processing inputs, not destroying everything.\n");
1202 #endif
1203     return;
1204   }
1205
1206   if (client->persist == GNUNET_YES)
1207     GNUNET_CONNECTION_persist_ (client->connection);
1208   GNUNET_CONNECTION_destroy (client->connection, GNUNET_NO);
1209   GNUNET_SERVER_mst_destroy (client->mst);
1210   GNUNET_free (client);
1211 }
1212
1213
1214 /**
1215  * Disable the "CORK" feature for communication with the given client,
1216  * forcing the OS to immediately flush the buffer on transmission
1217  * instead of potentially buffering multiple messages.
1218  *
1219  * @param client handle to the client
1220  * @return GNUNET_OK on success
1221  */
1222 int
1223 GNUNET_SERVER_client_disable_corking (struct GNUNET_SERVER_Client *client)
1224 {
1225   return GNUNET_CONNECTION_disable_corking (client->connection);
1226 }
1227
1228
1229 /**
1230  * Wrapper for transmission notification that calls the original
1231  * callback and update the last activity time for our connection.
1232  * 
1233  * @param cls the 'struct GNUNET_SERVER_Client'
1234  * @param size number of bytes we can transmit
1235  * @param buf where to copy the message 
1236  * @return number of bytes actually transmitted
1237  */
1238 static size_t
1239 transmit_ready_callback_wrapper (void *cls, size_t size, void *buf)
1240 {
1241   struct GNUNET_SERVER_Client *client = cls;
1242   size_t ret;
1243
1244   ret = client->callback (client->callback_cls, size, buf);
1245   if (ret > 0)
1246     client->last_activity = GNUNET_TIME_absolute_get ();
1247   return ret;
1248 }
1249
1250
1251 /**
1252  * Notify us when the server has enough space to transmit
1253  * a message of the given size to the given client.
1254  *
1255  * @param client client to transmit message to
1256  * @param size requested amount of buffer space
1257  * @param timeout after how long should we give up (and call
1258  *        notify with buf NULL and size 0)?
1259  * @param callback function to call when space is available
1260  * @param callback_cls closure for callback
1261  * @return non-NULL if the notify callback was queued; can be used
1262  *           to cancel the request using
1263  *           GNUNET_CONNECTION_notify_transmit_ready_cancel.
1264  *         NULL if we are already going to notify someone else (busy)
1265  */
1266 struct GNUNET_CONNECTION_TransmitHandle *
1267 GNUNET_SERVER_notify_transmit_ready (struct GNUNET_SERVER_Client *client,
1268                                      size_t size,
1269                                      struct GNUNET_TIME_Relative timeout,
1270                                      GNUNET_CONNECTION_TransmitReadyNotify
1271                                      callback, void *callback_cls)
1272 {
1273   client->callback_cls = callback_cls;
1274   client->callback = callback;
1275   return GNUNET_CONNECTION_notify_transmit_ready (client->connection, size,
1276                                                   timeout,
1277                                                   &transmit_ready_callback_wrapper,
1278                                                   client);
1279 }
1280
1281
1282 /**
1283  * Set the persistent flag on this client, used to setup client connection
1284  * to only be killed when the service it's connected to is actually dead.
1285  *
1286  * @param client the client to set the persistent flag on
1287  */
1288 void
1289 GNUNET_SERVER_client_persist_ (struct GNUNET_SERVER_Client *client)
1290 {
1291   client->persist = GNUNET_YES;
1292 }
1293
1294
1295 /**
1296  * Retrieve the unique id from the opaque defined GNUNET_SERVER_Client
1297  *
1298  * @param client the client
1299  * @return the unique id
1300  */
1301 uint64_t
1302 GNUNET_SERVER_client_get_id (struct GNUNET_SERVER_Client *client)
1303 {
1304   return client->id;
1305 }
1306
1307 /**
1308  * Resume receiving from this client, we are done processing the
1309  * current request.  This function must be called from within each
1310  * GNUNET_SERVER_MessageCallback (or its respective continuations).
1311  *
1312  * @param client client we were processing a message of
1313  * @param success GNUNET_OK to keep the connection open and
1314  *                          continue to receive
1315  *                GNUNET_NO to close the connection (normal behavior)
1316  *                GNUNET_SYSERR to close the connection (signal
1317  *                          serious error)
1318  */
1319 void
1320 GNUNET_SERVER_receive_done (struct GNUNET_SERVER_Client *client, int success)
1321 {
1322   if (client == NULL)
1323     return;
1324   GNUNET_assert (client->suspended > 0);
1325   client->suspended--;
1326   if (success != GNUNET_OK)
1327   {
1328 #if DEBUG_SERVER
1329     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1330                 "GNUNET_SERVER_receive_done called with failure indication\n");
1331 #endif
1332     GNUNET_SERVER_client_disconnect (client);
1333     return;
1334   }
1335   if (client->suspended > 0)
1336   {
1337 #if DEBUG_SERVER
1338     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1339                 "GNUNET_SERVER_receive_done called, but more clients pending\n");
1340 #endif
1341     return;
1342   }
1343   if (GNUNET_SCHEDULER_NO_TASK != client->warn_task)
1344   {
1345     GNUNET_SCHEDULER_cancel (client->warn_task);
1346     client->warn_task = GNUNET_SCHEDULER_NO_TASK;
1347   }
1348   if (client->in_process_client_buffer == GNUNET_YES)
1349   {
1350 #if DEBUG_SERVER
1351     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1352                 "GNUNET_SERVER_receive_done called while still in processing loop\n");
1353 #endif
1354     return;
1355   }
1356   if (client->server == NULL)
1357   {
1358     GNUNET_SERVER_client_disconnect (client);
1359     return;
1360   }
1361 #if DEBUG_SERVER
1362   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1363               "GNUNET_SERVER_receive_done causes restart in reading from the socket\n");
1364 #endif
1365   GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == client->restart_task);
1366   client->restart_task = GNUNET_SCHEDULER_add_now (&restart_processing, client);
1367 }
1368
1369
1370 /**
1371  * Configure this server's connections to continue handling client
1372  * requests as usual even after we get a shutdown signal.  The change
1373  * only applies to clients that connect to the server from the outside
1374  * using TCP after this call.  Clients managed previously or those
1375  * added using GNUNET_SERVER_connect_socket and
1376  * GNUNET_SERVER_connect_callback are not affected by this option.
1377  *
1378  * @param h server handle
1379  * @param do_ignore GNUNET_YES to ignore, GNUNET_NO to restore default
1380  */
1381 void
1382 GNUNET_SERVER_ignore_shutdown (struct GNUNET_SERVER_Handle *h, int do_ignore)
1383 {
1384   h->clients_ignore_shutdown = do_ignore;
1385 }
1386
1387 /* end of server.c */