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