indentation
[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
253 /**
254  * Scheduler says our listen socket is ready.  Process it!
255  *
256  * @param cls handle to our server for which we are processing the listen
257  *        socket
258  * @param tc reason why we are running right now
259  */
260 static void
261 process_listen_socket (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
262 {
263   struct GNUNET_SERVER_Handle *server = cls;
264   struct GNUNET_CONNECTION_Handle *sock;
265   struct GNUNET_SERVER_Client *client;
266   struct GNUNET_NETWORK_FDSet *r;
267   unsigned int i;
268
269   server->listen_task = GNUNET_SCHEDULER_NO_TASK;
270   r = GNUNET_NETWORK_fdset_create ();
271   i = 0;
272   while (NULL != server->listen_sockets[i])
273     GNUNET_NETWORK_fdset_set (r, server->listen_sockets[i++]);
274   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
275   {
276     /* ignore shutdown, someone else will take care of it! */
277     server->listen_task =
278         GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH,
279                                      GNUNET_SCHEDULER_NO_TASK,
280                                      GNUNET_TIME_UNIT_FOREVER_REL, r, NULL,
281                                      &process_listen_socket, server);
282     GNUNET_NETWORK_fdset_destroy (r);
283     return;
284   }
285   i = 0;
286   while (NULL != server->listen_sockets[i])
287   {
288     if (GNUNET_NETWORK_fdset_isset (tc->read_ready, server->listen_sockets[i]))
289     {
290       sock =
291           GNUNET_CONNECTION_create_from_accept (server->access,
292                                                 server->access_cls,
293                                                 server->listen_sockets[i]);
294       if (sock != NULL)
295       {
296 #if DEBUG_SERVER
297         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
298                     "Server accepted incoming connection.\n");
299 #endif
300         client = GNUNET_SERVER_connect_socket (server, sock);
301         GNUNET_CONNECTION_ignore_shutdown (sock,
302                                            server->clients_ignore_shutdown);
303         /* decrement reference count, we don't keep "client" alive */
304         GNUNET_SERVER_client_drop (client);
305       }
306     }
307     i++;
308   }
309   /* listen for more! */
310   server->listen_task =
311       GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH,
312                                    GNUNET_SCHEDULER_NO_TASK,
313                                    GNUNET_TIME_UNIT_FOREVER_REL, r, NULL,
314                                    &process_listen_socket, server);
315   GNUNET_NETWORK_fdset_destroy (r);
316 }
317
318
319 /**
320  * Create and initialize a listen socket for the server.
321  *
322  * @param serverAddr address to listen on
323  * @param socklen length of address
324  * @return NULL on error, otherwise the listen socket
325  */
326 static struct GNUNET_NETWORK_Handle *
327 open_listen_socket (const struct sockaddr *serverAddr, socklen_t socklen)
328 {
329   const static int on = 1;
330   struct GNUNET_NETWORK_Handle *sock;
331   uint16_t port;
332   int eno;
333
334   switch (serverAddr->sa_family)
335   {
336   case AF_INET:
337     port = ntohs (((const struct sockaddr_in *) serverAddr)->sin_port);
338     break;
339   case AF_INET6:
340     port = ntohs (((const struct sockaddr_in6 *) serverAddr)->sin6_port);
341     break;
342   case AF_UNIX:
343     port = 0;
344     break;
345   default:
346     GNUNET_break (0);
347     port = 0;
348     break;
349   }
350   sock = GNUNET_NETWORK_socket_create (serverAddr->sa_family, SOCK_STREAM, 0);
351   if (NULL == sock)
352   {
353     GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket");
354     errno = 0;
355     return NULL;
356   }
357   if (port != 0)
358   {
359     if (GNUNET_NETWORK_socket_setsockopt
360         (sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) != GNUNET_OK)
361       GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
362                            "setsockopt");
363 #ifdef IPV6_V6ONLY
364     if ((serverAddr->sa_family == AF_INET6) &&
365         (GNUNET_NETWORK_socket_setsockopt
366          (sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on)) != GNUNET_OK))
367       GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
368                            "setsockopt");
369 #endif
370   }
371   /* bind the socket */
372   if (GNUNET_NETWORK_socket_bind (sock, serverAddr, socklen) != GNUNET_OK)
373   {
374     eno = errno;
375     if (errno != EADDRINUSE)
376     {
377       /* we don't log 'EADDRINUSE' here since an IPv4 bind may
378        * fail if we already took the port on IPv6; if both IPv4 and
379        * IPv6 binds fail, then our caller will log using the
380        * errno preserved in 'eno' */
381       GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind");
382       if (port != 0)
383         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
384                     _
385                     ("`%s' failed for port %d (%s).\n"),
386                     "bind", port,
387                     (serverAddr->sa_family == AF_INET) ? "IPv4" : "IPv6");
388       eno = 0;
389     }
390     else
391     {
392       if (port != 0)
393         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
394                     _
395                     ("`%s' failed for port %d (%s): address already in use\n"),
396                     "bind", port,
397                     (serverAddr->sa_family == AF_INET) ? "IPv4" : "IPv6");
398       else if (serverAddr->sa_family == AF_UNIX)
399         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
400                     _
401                     ("`%s' failed for `%s': address already in use\n"),
402                     "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,
487                       void *access_cls,
488                       struct sockaddr *const *serverAddr,
489                       const socklen_t * socklen,
490                       struct GNUNET_TIME_Relative
491                       idle_timeout, int require_found)
492 {
493   struct GNUNET_NETWORK_Handle **lsocks;
494   unsigned int i;
495   unsigned int j;
496
497   i = 0;
498   while (serverAddr[i] != NULL)
499     i++;
500   if (i > 0)
501   {
502     lsocks = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (i + 1));
503     i = 0;
504     j = 0;
505     while (serverAddr[i] != NULL)
506     {
507       lsocks[j] = open_listen_socket (serverAddr[i], socklen[i]);
508       if (lsocks[j] != NULL)
509         j++;
510       i++;
511     }
512     if (j == 0)
513     {
514       if (errno != 0)
515         GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind");
516       GNUNET_free (lsocks);
517       lsocks = NULL;
518     }
519   }
520   else
521   {
522     lsocks = NULL;
523   }
524   return GNUNET_SERVER_create_with_sockets (access, access_cls,
525                                             lsocks,
526                                             idle_timeout, require_found);
527 }
528
529
530 /**
531  * Free resources held by this server.
532  *
533  * @param s server to destroy
534  */
535 void
536 GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *s)
537 {
538   struct HandlerList *hpos;
539   struct NotifyList *npos;
540   unsigned int i;
541
542 #if DEBUG_SERVER
543   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Server shutting down.\n");
544 #endif
545   if (GNUNET_SCHEDULER_NO_TASK != s->listen_task)
546   {
547     GNUNET_SCHEDULER_cancel (s->listen_task);
548     s->listen_task = GNUNET_SCHEDULER_NO_TASK;
549   }
550   if (s->listen_sockets != NULL)
551   {
552     i = 0;
553     while (s->listen_sockets[i] != NULL)
554       GNUNET_break (GNUNET_OK ==
555                     GNUNET_NETWORK_socket_close (s->listen_sockets[i++]));
556     GNUNET_free (s->listen_sockets);
557     s->listen_sockets = NULL;
558   }
559   while (s->clients != NULL)
560     GNUNET_SERVER_client_disconnect (s->clients);
561   while (NULL != (hpos = s->handlers))
562   {
563     s->handlers = hpos->next;
564     GNUNET_free (hpos);
565   }
566   while (NULL != (npos = s->disconnect_notify_list))
567   {
568     npos->callback (npos->callback_cls, NULL);
569     s->disconnect_notify_list = npos->next;
570     GNUNET_free (npos);
571   }
572   GNUNET_free (s);
573 }
574
575
576 /**
577  * Add additional handlers to an existing server.
578  *
579  * @param server the server to add handlers to
580  * @param handlers array of message handlers for
581  *        incoming messages; the last entry must
582  *        have "NULL" for the "callback"; multiple
583  *        entries for the same type are allowed,
584  *        they will be called in order of occurence.
585  *        These handlers can be removed later;
586  *        the handlers array must exist until removed
587  *        (or server is destroyed).
588  */
589 void
590 GNUNET_SERVER_add_handlers (struct GNUNET_SERVER_Handle *server,
591                             const struct GNUNET_SERVER_MessageHandler *handlers)
592 {
593   struct HandlerList *p;
594
595   p = GNUNET_malloc (sizeof (struct HandlerList));
596   p->handlers = handlers;
597   p->next = server->handlers;
598   server->handlers = p;
599 }
600
601
602 /**
603  * Task run to warn about missing calls to 'GNUNET_SERVER_receive_done'.
604  *
605  * @param cls our 'struct GNUNET_SERVER_Client*' to process more requests from
606  * @param tc scheduler context (unused)
607  */
608 static void
609 warn_no_receive_done (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
610 {
611   struct GNUNET_SERVER_Client *client = cls;
612
613   client->warn_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
614                                                     &warn_no_receive_done,
615                                                     client);
616   if (0 == (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
617     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
618                 _
619                 ("Processing code for message of type %u did not call GNUNET_SERVER_receive_done after %llums\n"),
620                 (unsigned int) client->warn_type,
621                 (unsigned long long)
622                 GNUNET_TIME_absolute_get_duration
623                 (client->warn_start).rel_value);
624 }
625
626
627 /**
628  * Disable the warning the server issues if a message is not acknowledged
629  * in a timely fashion.  Use this call if a client is intentionally delayed
630  * for a while.  Only applies to the current message.
631  *
632  * @param client client for which to disable the warning
633  */
634 void
635 GNUNET_SERVER_disable_receive_done_warning (struct GNUNET_SERVER_Client *client)
636 {
637   if (GNUNET_SCHEDULER_NO_TASK != client->warn_task)
638   {
639     GNUNET_SCHEDULER_cancel (client->warn_task);
640     client->warn_task = GNUNET_SCHEDULER_NO_TASK;
641   }
642 }
643
644
645 /**
646  * Inject a message into the server, pretend it came
647  * from the specified client.  Delivery of the message
648  * will happen instantly (if a handler is installed;
649  * otherwise the call does nothing).
650  *
651  * @param server the server receiving the message
652  * @param sender the "pretended" sender of the message
653  *        can be NULL!
654  * @param message message to transmit
655  * @return GNUNET_OK if the message was OK and the
656  *                   connection can stay open
657  *         GNUNET_SYSERR if the connection to the
658  *         client should be shut down
659  */
660 int
661 GNUNET_SERVER_inject (struct GNUNET_SERVER_Handle *server,
662                       struct GNUNET_SERVER_Client *sender,
663                       const struct GNUNET_MessageHeader *message)
664 {
665   struct HandlerList *pos;
666   const struct GNUNET_SERVER_MessageHandler *mh;
667   unsigned int i;
668   uint16_t type;
669   uint16_t size;
670   int found;
671
672   type = ntohs (message->type);
673   size = ntohs (message->size);
674 #if DEBUG_SERVER
675
676   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
677               "Server schedules transmission of %u-byte message of type %u to client.\n",
678               size, type);
679 #endif
680   pos = server->handlers;
681   found = GNUNET_NO;
682   while (pos != NULL)
683   {
684     i = 0;
685     while (pos->handlers[i].callback != NULL)
686     {
687       mh = &pos->handlers[i];
688       if ((mh->type == type) || (mh->type == GNUNET_MESSAGE_TYPE_ALL))
689       {
690         if ((mh->expected_size != 0) && (mh->expected_size != size))
691         {
692 #if GNUNET8_NETWORK_IS_DEAD
693           GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
694                       "Expected %u bytes for message of type %u, got %u\n",
695                       mh->expected_size, mh->type, size);
696           GNUNET_break_op (0);
697 #endif
698           return GNUNET_SYSERR;
699         }
700         if (sender != NULL)
701         {
702           if (0 == sender->suspended)
703           {
704             sender->warn_start = GNUNET_TIME_absolute_get ();
705             sender->warn_task =
706                 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
707                                               &warn_no_receive_done, sender);
708             sender->warn_type = type;
709           }
710           sender->suspended++;
711         }
712         mh->callback (mh->callback_cls, sender, message);
713         found = GNUNET_YES;
714       }
715       i++;
716     }
717     pos = pos->next;
718   }
719   if (found == GNUNET_NO)
720   {
721     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
722                 "Received message of unknown type %d\n", type);
723     if (server->require_found == GNUNET_YES)
724       return GNUNET_SYSERR;
725   }
726   return GNUNET_OK;
727 }
728
729
730 /**
731  * We are receiving an incoming message.  Process it.
732  *
733  * @param cls our closure (handle for the client)
734  * @param buf buffer with data received from network
735  * @param available number of bytes available in buf
736  * @param addr address of the sender
737  * @param addrlen length of addr
738  * @param errCode code indicating errors receiving, 0 for success
739  */
740 static void
741 process_incoming (void *cls,
742                   const void *buf,
743                   size_t available,
744                   const struct sockaddr *addr, socklen_t addrlen, int errCode);
745
746
747 /**
748  * Process messages from the client's message tokenizer until either
749  * the tokenizer is empty (and then schedule receiving more), or 
750  * until some handler is not immediately done (then wait for restart_processing)
751  * or shutdown.
752  *
753  * @param client the client to process, RC must have already been increased
754  *        using GNUNET_SERVER_client_keep and will be decreased by one in this
755  *        function
756  * @param ret GNUNET_NO to start processing from the buffer,
757  *            GNUNET_OK if the mst buffer is drained and we should instantly go back to receiving
758  *            GNUNET_SYSERR if we should instantly abort due to error in a previous step
759  */
760 static void
761 process_mst (struct GNUNET_SERVER_Client *client, int ret)
762 {
763   while ((ret != GNUNET_SYSERR) &&
764          (client->server != NULL) &&
765          (GNUNET_YES != client->shutdown_now) && (0 == client->suspended))
766   {
767     if (ret == GNUNET_OK)
768     {
769       client->receive_pending = GNUNET_YES;
770 #if DEBUG_SERVER
771       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
772                   "Server re-enters receive loop, timeout: %llu.\n",
773                   client->idle_timeout.rel_value);
774 #endif
775       GNUNET_CONNECTION_receive (client->connection,
776                                  GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
777                                  client->idle_timeout,
778                                  &process_incoming, client);
779       break;
780     }
781 #if DEBUG_SERVER
782     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
783                 "Server processes additional messages instantly.\n");
784 #endif
785     ret =
786         GNUNET_SERVER_mst_receive (client->mst, client, NULL, 0, GNUNET_NO,
787                                    GNUNET_YES);
788   }
789 #if DEBUG_SERVER
790   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
791               "Server leaves instant processing loop: ret = %d, server = %p, shutdown = %d, suspended = %u\n",
792               ret, client->server, client->shutdown_now, client->suspended);
793 #endif
794
795   if (ret == GNUNET_NO)
796   {
797 #if DEBUG_SERVER
798     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
799                 "Server has more data pending but is suspended.\n");
800 #endif
801     client->receive_pending = GNUNET_SYSERR;    /* data pending */
802   }
803   if ((ret == GNUNET_SYSERR) || (GNUNET_YES == client->shutdown_now))
804     GNUNET_SERVER_client_disconnect (client);
805   GNUNET_SERVER_client_drop (client);
806 }
807
808
809 /**
810  * We are receiving an incoming message.  Process it.
811  *
812  * @param cls our closure (handle for the client)
813  * @param buf buffer with data received from network
814  * @param available number of bytes available in buf
815  * @param addr address of the sender
816  * @param addrlen length of addr
817  * @param errCode code indicating errors receiving, 0 for success
818  */
819 static void
820 process_incoming (void *cls,
821                   const void *buf,
822                   size_t available,
823                   const struct sockaddr *addr, socklen_t addrlen, int errCode)
824 {
825   struct GNUNET_SERVER_Client *client = cls;
826   struct GNUNET_SERVER_Handle *server = client->server;
827   struct GNUNET_TIME_Absolute end;
828   struct GNUNET_TIME_Absolute now;
829   int ret;
830
831   GNUNET_assert (client->receive_pending == GNUNET_YES);
832   client->receive_pending = GNUNET_NO;
833   now = GNUNET_TIME_absolute_get ();
834   end = GNUNET_TIME_absolute_add (client->last_activity, client->idle_timeout);
835
836   if ((buf == NULL) && (available == 0) && (addr == NULL) && (errCode == 0) &&
837       (client->shutdown_now != GNUNET_YES) &&
838       (server != NULL) &&
839       (GNUNET_YES == GNUNET_CONNECTION_check (client->connection)) &&
840       (end.abs_value > now.abs_value))
841   {
842     /* wait longer, timeout changed (i.e. due to us sending) */
843 #if DEBUG_SERVER
844     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
845                 "Receive time out, but no disconnect due to sending (%p)\n",
846                 GNUNET_a2s (addr, addrlen));
847 #endif
848     client->receive_pending = GNUNET_YES;
849     GNUNET_CONNECTION_receive (client->connection,
850                                GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
851                                GNUNET_TIME_absolute_get_remaining (end),
852                                &process_incoming, client);
853     return;
854   }
855   if ((buf == NULL) ||
856       (available == 0) ||
857       (errCode != 0) ||
858       (server == NULL) ||
859       (client->shutdown_now == GNUNET_YES) ||
860       (GNUNET_YES != GNUNET_CONNECTION_check (client->connection)))
861   {
862     /* other side closed connection, error connecting, etc. */
863     GNUNET_SERVER_client_disconnect (client);
864     return;
865   }
866 #if DEBUG_SERVER
867   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
868               "Server receives %u bytes from `%s'.\n",
869               (unsigned int) available, GNUNET_a2s (addr, addrlen));
870 #endif
871   GNUNET_SERVER_client_keep (client);
872   client->last_activity = now;
873   ret =
874       GNUNET_SERVER_mst_receive (client->mst, client, buf, available, GNUNET_NO,
875                                  GNUNET_YES);
876   process_mst (client, ret);
877 }
878
879
880 /**
881  * Task run to start again receiving from the network
882  * and process requests.
883  *
884  * @param cls our 'struct GNUNET_SERVER_Client*' to process more requests from
885  * @param tc scheduler context (unused)
886  */
887 static void
888 restart_processing (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
889 {
890   struct GNUNET_SERVER_Client *client = cls;
891   struct GNUNET_SERVER_Handle *server = client->server;
892
893   client->restart_task = GNUNET_SCHEDULER_NO_TASK;
894   if ((0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) &&
895       (GNUNET_NO == server->clients_ignore_shutdown))
896   {
897     GNUNET_SERVER_client_disconnect (client);
898     return;
899   }
900   if (client->receive_pending == GNUNET_NO)
901   {
902 #if DEBUG_SERVER
903     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
904                 "Server begins to read again from client.\n");
905 #endif
906     client->receive_pending = GNUNET_YES;
907     GNUNET_CONNECTION_receive (client->connection,
908                                GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
909                                client->idle_timeout, &process_incoming, client);
910     return;
911   }
912 #if DEBUG_SERVER
913   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
914               "Server continues processing messages still in the buffer.\n");
915 #endif
916   GNUNET_SERVER_client_keep (client);
917   client->receive_pending = GNUNET_NO;
918   process_mst (client, GNUNET_NO);
919 }
920
921
922 /**
923  * This function is called whenever our inbound message tokenizer has
924  * received a complete message.
925  *
926  * @param cls closure (struct GNUNET_SERVER_Handle)
927  * @param client identification of the client (struct GNUNET_SERVER_Client*)
928  * @param message the actual message
929  */
930 static void
931 client_message_tokenizer_callback (void *cls,
932                                    void *client,
933                                    const struct GNUNET_MessageHeader *message)
934 {
935   struct GNUNET_SERVER_Handle *server = cls;
936   struct GNUNET_SERVER_Client *sender = client;
937   int ret;
938
939 #if DEBUG_SERVER
940
941   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
942               "Tokenizer gives server message of type %u from client\n",
943               ntohs (message->type));
944 #endif
945   sender->in_process_client_buffer = GNUNET_YES;
946   ret = GNUNET_SERVER_inject (server, sender, message);
947   sender->in_process_client_buffer = GNUNET_NO;
948   if (GNUNET_OK != ret)
949     GNUNET_SERVER_client_disconnect (sender);
950 }
951
952
953 /**
954  * Add a TCP socket-based connection to the set of handles managed by
955  * this server.  Use this function for outgoing (P2P) connections that
956  * we initiated (and where this server should process incoming
957  * messages).
958  *
959  * @param server the server to use
960  * @param connection the connection to manage (client must
961  *        stop using this connection from now on)
962  * @return the client handle (client should call
963  *         "client_drop" on the return value eventually)
964  */
965 struct GNUNET_SERVER_Client *
966 GNUNET_SERVER_connect_socket (struct
967                               GNUNET_SERVER_Handle
968                               *server,
969                               struct GNUNET_CONNECTION_Handle *connection)
970 {
971   struct GNUNET_SERVER_Client *client;
972
973   client = GNUNET_malloc (sizeof (struct GNUNET_SERVER_Client));
974   client->connection = connection;
975   client->mst = GNUNET_SERVER_mst_create (&client_message_tokenizer_callback,
976                                           server);
977   client->reference_count = 1;
978   client->server = server;
979   client->last_activity = GNUNET_TIME_absolute_get ();
980   client->next = server->clients;
981   client->idle_timeout = server->idle_timeout;
982   server->clients = client;
983   client->receive_pending = GNUNET_YES;
984   client->callback = NULL;
985   client->callback_cls = NULL;
986   GNUNET_CONNECTION_receive (client->connection,
987                              GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
988                              client->idle_timeout, &process_incoming, client);
989   return client;
990 }
991
992
993 /**
994  * Change the timeout for a particular client.  Decreasing the timeout
995  * may not go into effect immediately (only after the previous timeout
996  * times out or activity happens on the socket).
997  *
998  * @param client the client to update
999  * @param timeout new timeout for activities on the socket
1000  */
1001 void
1002 GNUNET_SERVER_client_set_timeout (struct GNUNET_SERVER_Client *client,
1003                                   struct GNUNET_TIME_Relative timeout)
1004 {
1005   client->idle_timeout = timeout;
1006 }
1007
1008
1009 /**
1010  * Notify the server that the given client handle should
1011  * be kept (keeps the connection up if possible, increments
1012  * the internal reference counter).
1013  *
1014  * @param client the client to keep
1015  */
1016 void
1017 GNUNET_SERVER_client_keep (struct GNUNET_SERVER_Client *client)
1018 {
1019   client->reference_count++;
1020 }
1021
1022
1023 /**
1024  * Notify the server that the given client handle is no
1025  * longer required.  Decrements the reference counter.  If
1026  * that counter reaches zero an inactive connection maybe
1027  * closed.
1028  *
1029  * @param client the client to drop
1030  */
1031 void
1032 GNUNET_SERVER_client_drop (struct GNUNET_SERVER_Client *client)
1033 {
1034   GNUNET_assert (client->reference_count > 0);
1035   client->reference_count--;
1036   if ((client->shutdown_now == GNUNET_YES) && (client->reference_count == 0))
1037     GNUNET_SERVER_client_disconnect (client);
1038 }
1039
1040
1041 /**
1042  * Obtain the network address of the other party.
1043  *
1044  * @param client the client to get the address for
1045  * @param addr where to store the address
1046  * @param addrlen where to store the length of the address
1047  * @return GNUNET_OK on success
1048  */
1049 int
1050 GNUNET_SERVER_client_get_address (struct GNUNET_SERVER_Client *client,
1051                                   void **addr, size_t * addrlen)
1052 {
1053   return GNUNET_CONNECTION_get_address (client->connection, addr, addrlen);
1054 }
1055
1056
1057 /**
1058  * Ask the server to notify us whenever a client disconnects.
1059  * This function is called whenever the actual network connection
1060  * is closed; the reference count may be zero or larger than zero
1061  * at this point.
1062  *
1063  * @param server the server manageing the clients
1064  * @param callback function to call on disconnect
1065  * @param callback_cls closure for callback
1066  */
1067 void
1068 GNUNET_SERVER_disconnect_notify (struct GNUNET_SERVER_Handle *server,
1069                                  GNUNET_SERVER_DisconnectCallback callback,
1070                                  void *callback_cls)
1071 {
1072   struct NotifyList *n;
1073
1074   n = GNUNET_malloc (sizeof (struct NotifyList));
1075   n->callback = callback;
1076   n->callback_cls = callback_cls;
1077   n->next = server->disconnect_notify_list;
1078   server->disconnect_notify_list = n;
1079 }
1080
1081
1082 /**
1083  * Ask the server to stop notifying us whenever a client disconnects.
1084  *
1085  * @param server the server manageing the clients
1086  * @param callback function to call on disconnect
1087  * @param callback_cls closure for callback
1088  */
1089 void
1090 GNUNET_SERVER_disconnect_notify_cancel (struct GNUNET_SERVER_Handle *server,
1091                                         GNUNET_SERVER_DisconnectCallback
1092                                         callback, void *callback_cls)
1093 {
1094   struct NotifyList *pos;
1095   struct NotifyList *prev;
1096
1097   prev = NULL;
1098   pos = server->disconnect_notify_list;
1099   while (pos != NULL)
1100   {
1101     if ((pos->callback == callback) && (pos->callback_cls == callback_cls))
1102       break;
1103     prev = pos;
1104     pos = pos->next;
1105   }
1106   if (pos == NULL)
1107   {
1108     GNUNET_break (0);
1109     return;
1110   }
1111   if (prev == NULL)
1112     server->disconnect_notify_list = pos->next;
1113   else
1114     prev->next = pos->next;
1115   GNUNET_free (pos);
1116 }
1117
1118
1119 /**
1120  * Ask the server to disconnect from the given client.
1121  * This is the same as returning GNUNET_SYSERR from a message
1122  * handler, except that it allows dropping of a client even
1123  * when not handling a message from that client.
1124  *
1125  * @param client the client to disconnect from
1126  */
1127 void
1128 GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client)
1129 {
1130   struct GNUNET_SERVER_Client *prev;
1131   struct GNUNET_SERVER_Client *pos;
1132   struct GNUNET_SERVER_Handle *server;
1133   struct NotifyList *n;
1134   unsigned int rc;
1135
1136 #if DEBUG_SERVER
1137   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1138               "Client is being disconnected from the server.\n");
1139 #endif
1140   if (client->restart_task != GNUNET_SCHEDULER_NO_TASK)
1141   {
1142     GNUNET_SCHEDULER_cancel (client->restart_task);
1143     client->restart_task = GNUNET_SCHEDULER_NO_TASK;
1144   }
1145   if (client->warn_task != GNUNET_SCHEDULER_NO_TASK)
1146   {
1147     GNUNET_SCHEDULER_cancel (client->warn_task);
1148     client->warn_task = GNUNET_SCHEDULER_NO_TASK;
1149   }
1150   if (GNUNET_YES == client->receive_pending)
1151   {
1152     GNUNET_CONNECTION_receive_cancel (client->connection);
1153     client->receive_pending = GNUNET_NO;
1154   }
1155
1156   rc = client->reference_count;
1157   if (client->server != NULL)
1158   {
1159     server = client->server;
1160     client->server = NULL;
1161     client->shutdown_now = GNUNET_YES;
1162     prev = NULL;
1163     pos = server->clients;
1164     while ((pos != NULL) && (pos != client))
1165     {
1166       prev = pos;
1167       pos = pos->next;
1168     }
1169     GNUNET_assert (pos != NULL);
1170     if (prev == NULL)
1171       server->clients = pos->next;
1172     else
1173       prev->next = pos->next;
1174     if (client->restart_task != GNUNET_SCHEDULER_NO_TASK)
1175     {
1176       GNUNET_SCHEDULER_cancel (client->restart_task);
1177       client->restart_task = GNUNET_SCHEDULER_NO_TASK;
1178     }
1179     if (client->warn_task != GNUNET_SCHEDULER_NO_TASK)
1180     {
1181       GNUNET_SCHEDULER_cancel (client->warn_task);
1182       client->warn_task = GNUNET_SCHEDULER_NO_TASK;
1183     }
1184     n = server->disconnect_notify_list;
1185     while (n != NULL)
1186     {
1187       n->callback (n->callback_cls, client);
1188       n = n->next;
1189     }
1190   }
1191   if (rc > 0)
1192   {
1193 #if DEBUG_SERVER
1194     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1195                 "RC still positive, not destroying everything.\n");
1196 #endif
1197     return;
1198   }
1199   if (client->in_process_client_buffer == GNUNET_YES)
1200   {
1201 #if DEBUG_SERVER
1202     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1203                 "Still processing inputs, not destroying everything.\n");
1204 #endif
1205     return;
1206   }
1207
1208   if (client->persist == GNUNET_YES)
1209     GNUNET_CONNECTION_persist_ (client->connection);
1210   GNUNET_CONNECTION_destroy (client->connection, GNUNET_NO);
1211   GNUNET_SERVER_mst_destroy (client->mst);
1212   GNUNET_free (client);
1213 }
1214
1215
1216 /**
1217  * Disable the "CORK" feature for communication with the given client,
1218  * forcing the OS to immediately flush the buffer on transmission
1219  * instead of potentially buffering multiple messages.
1220  *
1221  * @param client handle to the client
1222  * @return GNUNET_OK on success
1223  */
1224 int
1225 GNUNET_SERVER_client_disable_corking (struct GNUNET_SERVER_Client *client)
1226 {
1227   return GNUNET_CONNECTION_disable_corking (client->connection);
1228 }
1229
1230
1231 /**
1232  * Wrapper for transmission notification that calls the original
1233  * callback and update the last activity time for our connection.
1234  * 
1235  * @param cls the 'struct GNUNET_SERVER_Client'
1236  * @param size number of bytes we can transmit
1237  * @param buf where to copy the message 
1238  * @return number of bytes actually transmitted
1239  */
1240 static size_t
1241 transmit_ready_callback_wrapper (void *cls, size_t size, void *buf)
1242 {
1243   struct GNUNET_SERVER_Client *client = cls;
1244   size_t ret;
1245
1246   ret = client->callback (client->callback_cls, size, buf);
1247   if (ret > 0)
1248     client->last_activity = GNUNET_TIME_absolute_get ();
1249   return ret;
1250 }
1251
1252
1253 /**
1254  * Notify us when the server has enough space to transmit
1255  * a message of the given size to the given client.
1256  *
1257  * @param client client to transmit message to
1258  * @param size requested amount of buffer space
1259  * @param timeout after how long should we give up (and call
1260  *        notify with buf NULL and size 0)?
1261  * @param callback function to call when space is available
1262  * @param callback_cls closure for callback
1263  * @return non-NULL if the notify callback was queued; can be used
1264  *           to cancel the request using
1265  *           GNUNET_CONNECTION_notify_transmit_ready_cancel.
1266  *         NULL if we are already going to notify someone else (busy)
1267  */
1268 struct GNUNET_CONNECTION_TransmitHandle *
1269 GNUNET_SERVER_notify_transmit_ready (struct GNUNET_SERVER_Client *client,
1270                                      size_t size,
1271                                      struct GNUNET_TIME_Relative timeout,
1272                                      GNUNET_CONNECTION_TransmitReadyNotify
1273                                      callback, void *callback_cls)
1274 {
1275   client->callback_cls = callback_cls;
1276   client->callback = callback;
1277   return GNUNET_CONNECTION_notify_transmit_ready (client->connection,
1278                                                   size,
1279                                                   timeout,
1280                                                   &transmit_ready_callback_wrapper,
1281                                                   client);
1282 }
1283
1284
1285 /**
1286  * Set the persistent flag on this client, used to setup client connection
1287  * to only be killed when the service it's connected to is actually dead.
1288  *
1289  * @param client the client to set the persistent flag on
1290  */
1291 void
1292 GNUNET_SERVER_client_persist_ (struct GNUNET_SERVER_Client *client)
1293 {
1294   client->persist = GNUNET_YES;
1295 }
1296
1297
1298 /**
1299  * Resume receiving from this client, we are done processing the
1300  * current request.  This function must be called from within each
1301  * GNUNET_SERVER_MessageCallback (or its respective continuations).
1302  *
1303  * @param client client we were processing a message of
1304  * @param success GNUNET_OK to keep the connection open and
1305  *                          continue to receive
1306  *                GNUNET_NO to close the connection (normal behavior)
1307  *                GNUNET_SYSERR to close the connection (signal
1308  *                          serious error)
1309  */
1310 void
1311 GNUNET_SERVER_receive_done (struct GNUNET_SERVER_Client *client, int success)
1312 {
1313   if (client == NULL)
1314     return;
1315   GNUNET_assert (client->suspended > 0);
1316   client->suspended--;
1317   if (success != GNUNET_OK)
1318   {
1319 #if DEBUG_SERVER
1320     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1321                 "GNUNET_SERVER_receive_done called with failure indication\n");
1322 #endif
1323     GNUNET_SERVER_client_disconnect (client);
1324     return;
1325   }
1326   if (client->suspended > 0)
1327   {
1328 #if DEBUG_SERVER
1329     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1330                 "GNUNET_SERVER_receive_done called, but more clients pending\n");
1331 #endif
1332     return;
1333   }
1334   if (GNUNET_SCHEDULER_NO_TASK != client->warn_task)
1335   {
1336     GNUNET_SCHEDULER_cancel (client->warn_task);
1337     client->warn_task = GNUNET_SCHEDULER_NO_TASK;
1338   }
1339   if (client->in_process_client_buffer == GNUNET_YES)
1340   {
1341 #if DEBUG_SERVER
1342     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1343                 "GNUNET_SERVER_receive_done called while still in processing loop\n");
1344 #endif
1345     return;
1346   }
1347   if (client->server == NULL)
1348   {
1349     GNUNET_SERVER_client_disconnect (client);
1350     return;
1351   }
1352 #if DEBUG_SERVER
1353   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1354               "GNUNET_SERVER_receive_done causes restart in reading from the socket\n");
1355 #endif
1356   GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == client->restart_task);
1357   client->restart_task = GNUNET_SCHEDULER_add_now (&restart_processing, client);
1358 }
1359
1360
1361 /**
1362  * Configure this server's connections to continue handling client
1363  * requests as usual even after we get a shutdown signal.  The change
1364  * only applies to clients that connect to the server from the outside
1365  * using TCP after this call.  Clients managed previously or those
1366  * added using GNUNET_SERVER_connect_socket and
1367  * GNUNET_SERVER_connect_callback are not affected by this option.
1368  *
1369  * @param h server handle
1370  * @param do_ignore GNUNET_YES to ignore, GNUNET_NO to restore default
1371  */
1372 void
1373 GNUNET_SERVER_ignore_shutdown (struct GNUNET_SERVER_Handle *h, int do_ignore)
1374 {
1375   h->clients_ignore_shutdown = do_ignore;
1376 }
1377
1378 /* end of server.c */