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