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