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