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