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