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