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