finishing gnunet-nat-server
[oweals/gnunet.git] / src / util / server.c
1 /*
2      This file is part of GNUnet.
3      (C) 2009 Christian Grothoff (and other contributing authors)
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 2, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21 /**
22  * @file util/server.c
23  * @brief library for building GNUnet network servers
24  * @author Christian Grothoff
25  */
26
27 #include "platform.h"
28 #include "gnunet_common.h"
29 #include "gnunet_connection_lib.h"
30 #include "gnunet_scheduler_lib.h"
31 #include "gnunet_server_lib.h"
32 #include "gnunet_time_lib.h"
33 #include "gnunet_disk_lib.h"
34 #include "gnunet_protocols.h"
35
36 #define DEBUG_SERVER GNUNET_NO
37
38 /**
39  * List of arrays of message handlers.
40  */
41 struct HandlerList
42 {
43   /**
44    * This is a linked list.
45    */
46   struct HandlerList *next;
47
48   /**
49    * NULL-terminated array of handlers.
50    */
51   const struct GNUNET_SERVER_MessageHandler *handlers;
52 };
53
54
55 /**
56  * List of arrays of message handlers.
57  */
58 struct NotifyList
59 {
60   /**
61    * This is a linked list.
62    */
63   struct NotifyList *next;
64
65   /**
66    * Function to call.
67    */
68   GNUNET_SERVER_DisconnectCallback callback;
69
70   /**
71    * Closure for callback.
72    */
73   void *callback_cls;
74 };
75
76
77 /**
78  * @brief handle for a server
79  */
80 struct GNUNET_SERVER_Handle
81 {
82   /**
83    * List of handlers for incoming messages.
84    */
85   struct HandlerList *handlers;
86
87   /**
88    * List of our current clients.
89    */
90   struct GNUNET_SERVER_Client *clients;
91
92   /**
93    * Linked list of functions to call on disconnects by clients.
94    */
95   struct NotifyList *disconnect_notify_list;
96
97   /**
98    * Function to call for access control.
99    */
100   GNUNET_CONNECTION_AccessCheck access;
101
102   /**
103    * Closure for access.
104    */
105   void *access_cls;
106
107   /**
108    * NULL-terminated array of sockets used to listen for new
109    * connections.
110    */
111   struct GNUNET_NETWORK_Handle **listen_sockets;
112
113   /**
114    * After how long should an idle connection time
115    * out (on write).
116    */
117   struct GNUNET_TIME_Relative idle_timeout;
118
119   /**
120    * Task scheduled to do the listening.
121    */
122   GNUNET_SCHEDULER_TaskIdentifier listen_task;
123
124   /**
125    * Do we ignore messages of types that we do not understand or do we
126    * require that a handler is found (and if not kill the connection)?
127    */
128   int require_found;
129
130   /**
131    * Should all of the clients of this server continue to process
132    * connections as usual even if we get a shutdown request? (the
133    * listen socket always ignores shutdown).
134    */
135   int clients_ignore_shutdown;
136
137 };
138
139
140 /**
141  * @brief handle for a client of the server
142  */
143 struct GNUNET_SERVER_Client
144 {
145
146   /**
147    * This is a linked list.
148    */
149   struct GNUNET_SERVER_Client *next;
150
151   /**
152    * Processing of incoming data.
153    */
154   struct GNUNET_SERVER_MessageStreamTokenizer *mst;
155
156   /**
157    * Server that this client belongs to.
158    */
159   struct GNUNET_SERVER_Handle *server;
160
161   /**
162    * Client closure for callbacks.
163    */
164   struct GNUNET_CONNECTION_Handle *connection;
165
166   /**
167    * ID of task used to restart processing.
168    */
169   GNUNET_SCHEDULER_TaskIdentifier restart_task;
170
171   /**
172    * Task that warns about missing calls to 'GNUNET_SERVER_receive_done'.
173    */
174   GNUNET_SCHEDULER_TaskIdentifier warn_task;
175
176   /**
177    * Time when the warn task was started.
178    */
179   struct GNUNET_TIME_Absolute warn_start;
180
181   /**
182    * Last activity on this socket (used to time it out
183    * if reference_count == 0).
184    */
185   struct GNUNET_TIME_Absolute last_activity;
186
187   /**
188    *
189    */
190   GNUNET_CONNECTION_TransmitReadyNotify callback;
191
192   /**
193    * callback
194    */
195   void *callback_cls;
196
197   /**
198    * After how long should an idle connection time
199    * out (on write).
200    */
201   struct GNUNET_TIME_Relative idle_timeout;
202
203   /**
204    * Number of external entities with a reference to
205    * this client object.
206    */
207   unsigned int reference_count;
208
209   /**
210    * Was processing if incoming messages suspended while
211    * we were still processing data already received?
212    * This is a counter saying how often processing was
213    * suspended (once per handler invoked).
214    */
215   unsigned int suspended;
216
217   /**
218    * Are we currently in the "process_client_buffer" function (and
219    * will hence restart the receive job on exit if suspended == 0 once
220    * we are done?).  If this is set, then "receive_done" will
221    * essentially only decrement suspended; if this is not set, then
222    * "receive_done" may need to restart the receive process (either
223    * from the side-buffer or via select/recv).
224    */
225   int in_process_client_buffer;
226
227   /**
228    * We're about to close down this client due to some serious
229    * error.
230    */
231   int shutdown_now;
232
233   /**
234    * Are we currently trying to receive? (YES if we are, NO if we are not,
235    * SYSERR if data is already available in MST).
236    */
237   int receive_pending;
238
239   /**
240    * Persist the file handle for this client no matter what happens,
241    * force the OS to close once the process actually dies.  Should only
242    * be used in special cases!
243    */
244   int persist;
245   
246   /**
247    * Type of last message processed (for warn_no_receive_done).
248    */
249   uint16_t warn_type;
250 };
251
252
253 /**
254  * Scheduler says our listen socket is ready.  Process it!
255  *
256  * @param cls handle to our server for which we are processing the listen
257  *        socket
258  * @param tc reason why we are running right now
259  */
260 static void
261 process_listen_socket (void *cls,
262                        const struct GNUNET_SCHEDULER_TaskContext *tc)
263 {
264   struct GNUNET_SERVER_Handle *server = cls;
265   struct GNUNET_CONNECTION_Handle *sock;
266   struct GNUNET_SERVER_Client *client;
267   struct GNUNET_NETWORK_FDSet *r;
268   unsigned int i;
269
270   server->listen_task = GNUNET_SCHEDULER_NO_TASK;
271   r = GNUNET_NETWORK_fdset_create ();
272   i = 0;
273   while (NULL != server->listen_sockets[i])
274     GNUNET_NETWORK_fdset_set (r, server->listen_sockets[i++]);
275   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
276     {
277       /* ignore shutdown, someone else will take care of it! */
278       server->listen_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH,
279                                                          GNUNET_SCHEDULER_NO_TASK,
280                                                          GNUNET_TIME_UNIT_FOREVER_REL,
281                                                          r, NULL,
282                                                          &process_listen_socket,
283                                                          server);
284       GNUNET_NETWORK_fdset_destroy (r);
285       return;
286     }
287   i = 0;
288   while (NULL != server->listen_sockets[i])
289     {
290       if (GNUNET_NETWORK_fdset_isset
291           (tc->read_ready, server->listen_sockets[i]))
292         {
293           sock =
294             GNUNET_CONNECTION_create_from_accept (server->access,
295                                                   server->access_cls,
296                                                   server->listen_sockets[i]);
297           if (sock != NULL)
298             {
299 #if DEBUG_SERVER
300               GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
301                           "Server accepted incoming connection.\n");
302 #endif
303               client = GNUNET_SERVER_connect_socket (server, sock);
304               GNUNET_CONNECTION_ignore_shutdown (sock,
305                                                  server->clients_ignore_shutdown);
306               /* decrement reference count, we don't keep "client" alive */
307               GNUNET_SERVER_client_drop (client);
308             }
309         }
310       i++;
311     }
312   /* listen for more! */
313   server->listen_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH,
314                                                      GNUNET_SCHEDULER_NO_TASK,
315                                                      GNUNET_TIME_UNIT_FOREVER_REL,
316                                                      r, NULL,
317                                                      &process_listen_socket,
318                                                      server);
319   GNUNET_NETWORK_fdset_destroy (r);
320 }
321
322
323 /**
324  * Create and initialize a listen socket for the server.
325  *
326  * @param serverAddr address to listen on
327  * @param socklen length of address
328  * @return NULL on error, otherwise the listen socket
329  */
330 static struct GNUNET_NETWORK_Handle *
331 open_listen_socket (const struct sockaddr *serverAddr, socklen_t socklen)
332 {
333   const static int on = 1;
334   struct GNUNET_NETWORK_Handle *sock;
335   uint16_t port;
336   int eno;
337
338   switch (serverAddr->sa_family)
339     {
340     case AF_INET:
341       port = ntohs (((const struct sockaddr_in *) serverAddr)->sin_port);
342       break;
343     case AF_INET6:
344       port = ntohs (((const struct sockaddr_in6 *) serverAddr)->sin6_port);
345       break;
346     case AF_UNIX:
347       port = 0;
348       break;
349     default:
350       GNUNET_break (0);
351       port = 0;
352       break;
353     }
354   sock = GNUNET_NETWORK_socket_create (serverAddr->sa_family, SOCK_STREAM, 0);
355   if (NULL == sock)
356     {
357       GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket");
358       errno = 0;
359       return NULL;
360     }
361   if (port != 0) 
362     {
363       if (GNUNET_NETWORK_socket_setsockopt
364           (sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) != GNUNET_OK)
365         GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
366                              "setsockopt");
367 #ifdef IPV6_V6ONLY
368       if ( (serverAddr->sa_family == AF_INET6) &&
369            (GNUNET_NETWORK_socket_setsockopt
370             (sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on)) != GNUNET_OK) )
371         GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
372                              "setsockopt");
373 #endif
374     }
375   /* bind the socket */
376   if (GNUNET_NETWORK_socket_bind (sock, serverAddr, socklen) != GNUNET_OK)
377     {
378       eno = errno;
379       if (errno != EADDRINUSE)
380         {
381           /* we don't log 'EADDRINUSE' here since an IPv4 bind may
382              fail if we already took the port on IPv6; if both IPv4 and
383              IPv6 binds fail, then our caller will log using the
384              errno preserved in 'eno' */
385           GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind");
386           if (port != 0)
387             GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
388                         _
389                         ("`%s' failed for port %d (%s).\n"),
390                         "bind", port,
391                         (serverAddr->sa_family == AF_INET) ? "IPv4" : "IPv6");
392           eno = 0;
393         }
394       else
395         {
396           if (port != 0)
397             GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
398                         _
399                         ("`%s' failed for port %d (%s): address already in use\n"),
400                         "bind", port,
401                         (serverAddr->sa_family == AF_INET) ? "IPv4" : "IPv6");
402           else if (serverAddr->sa_family == AF_UNIX)
403             GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
404                         _
405                         ("`%s' failed for `%s': address already in use\n"),
406                         "bind", 
407                         ((const struct sockaddr_un*) serverAddr)->sun_path);
408
409         }
410       GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
411       errno = eno;
412       return NULL;
413     }
414   if (GNUNET_OK != GNUNET_NETWORK_socket_listen (sock, 5))
415     {
416       GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "listen");
417       GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
418       errno = 0;
419       return NULL;
420     }
421 #if DEBUG_SERVER
422   if (port != 0)
423     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
424                 "Server starts to listen on port %u.\n", port);
425 #endif
426   return sock;
427 }
428
429
430 /**
431  * Create a new server.
432  *
433  * @param access function for access control
434  * @param access_cls closure for access
435  * @param lsocks NULL-terminated array of listen sockets
436  * @param idle_timeout after how long should we timeout idle connections?
437  * @param require_found if YES, connections sending messages of unknown type
438  *        will be closed
439  * @return handle for the new server, NULL on error
440  *         (typically, "port" already in use)
441  */
442 struct GNUNET_SERVER_Handle *
443 GNUNET_SERVER_create_with_sockets (GNUNET_CONNECTION_AccessCheck access, void *access_cls,
444                                    struct GNUNET_NETWORK_Handle **lsocks,
445                                    struct GNUNET_TIME_Relative
446                                    idle_timeout,
447                                    int require_found)
448 {
449   struct GNUNET_SERVER_Handle *ret;
450   struct GNUNET_NETWORK_FDSet *r;
451   int i;
452
453   ret = GNUNET_malloc (sizeof (struct GNUNET_SERVER_Handle));
454   ret->idle_timeout = idle_timeout;
455   ret->listen_sockets = lsocks;
456   ret->access = access;
457   ret->access_cls = access_cls;
458   ret->require_found = require_found;
459   if (lsocks != NULL)
460     {
461       r = GNUNET_NETWORK_fdset_create ();
462       i = 0;
463       while (NULL != ret->listen_sockets[i])
464         GNUNET_NETWORK_fdset_set (r, ret->listen_sockets[i++]);
465       ret->listen_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH,
466                                                       GNUNET_SCHEDULER_NO_TASK,
467                                                       GNUNET_TIME_UNIT_FOREVER_REL,
468                                                       r, NULL,
469                                                       &process_listen_socket,
470                                                       ret);
471       GNUNET_NETWORK_fdset_destroy (r);
472     }
473   return ret;
474 }
475
476
477 /**
478  * Create a new server.
479  *
480  * @param access function for access control
481  * @param access_cls closure for access
482  * @param serverAddr address to listen on (including port), NULL terminated array
483  * @param socklen length of serverAddr
484  * @param idle_timeout after how long should we timeout idle connections?
485  * @param require_found if YES, connections sending messages of unknown type
486  *        will be closed
487  * @return handle for the new server, NULL on error
488  *         (typically, "port" already in use)
489  */
490 struct GNUNET_SERVER_Handle *
491 GNUNET_SERVER_create (GNUNET_CONNECTION_AccessCheck access,
492                       void *access_cls,
493                       struct sockaddr *const *serverAddr,
494                       const socklen_t * socklen,
495                       struct GNUNET_TIME_Relative
496                       idle_timeout, int require_found)
497 {
498   struct GNUNET_NETWORK_Handle **lsocks;
499   unsigned int i;
500   unsigned int j;
501
502   i = 0;
503   while (serverAddr[i] != NULL)
504     i++;
505   if (i > 0)
506     {
507       lsocks =
508         GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (i + 1));
509       i = 0;
510       j = 0;
511       while (serverAddr[i] != NULL)
512         {
513           lsocks[j] = open_listen_socket (serverAddr[i], socklen[i]);
514           if (lsocks[j] != NULL)
515             j++;
516           i++;
517         }
518       if (j == 0)
519         {
520           if (errno != 0)
521             GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind");          
522           GNUNET_free (lsocks);
523           lsocks = NULL;
524         }
525     }
526   else
527     {
528       lsocks = NULL;
529     }
530   return GNUNET_SERVER_create_with_sockets (access, access_cls,
531                                             lsocks,
532                                             idle_timeout,
533                                             require_found);
534 }
535
536
537 /**
538  * Free resources held by this server.
539  *
540  * @param s server to destroy
541  */
542 void
543 GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *s)
544 {
545   struct HandlerList *hpos;
546   struct NotifyList *npos;
547   unsigned int i;
548
549 #if DEBUG_SERVER
550   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Server shutting down.\n");
551 #endif
552   if (GNUNET_SCHEDULER_NO_TASK != s->listen_task)
553     {
554       GNUNET_SCHEDULER_cancel (s->listen_task);
555       s->listen_task = GNUNET_SCHEDULER_NO_TASK;
556     }
557   if (s->listen_sockets != NULL)
558     {
559       i = 0;
560       while (s->listen_sockets[i] != NULL)
561         GNUNET_break (GNUNET_OK ==
562                       GNUNET_NETWORK_socket_close (s->listen_sockets[i++]));
563       GNUNET_free (s->listen_sockets);
564       s->listen_sockets = NULL;
565     }
566   while (s->clients != NULL)
567     GNUNET_SERVER_client_disconnect (s->clients);
568   while (NULL != (hpos = s->handlers))
569     {
570       s->handlers = hpos->next;
571       GNUNET_free (hpos);
572     }
573   while (NULL != (npos = s->disconnect_notify_list))
574     {
575       npos->callback (npos->callback_cls, NULL);
576       s->disconnect_notify_list = npos->next;
577       GNUNET_free (npos);
578     }
579   GNUNET_free (s);
580 }
581
582
583 /**
584  * Add additional handlers to an existing server.
585  *
586  * @param server the server to add handlers to
587  * @param handlers array of message handlers for
588  *        incoming messages; the last entry must
589  *        have "NULL" for the "callback"; multiple
590  *        entries for the same type are allowed,
591  *        they will be called in order of occurence.
592  *        These handlers can be removed later;
593  *        the handlers array must exist until removed
594  *        (or server is destroyed).
595  */
596 void
597 GNUNET_SERVER_add_handlers (struct GNUNET_SERVER_Handle *server,
598                             const struct GNUNET_SERVER_MessageHandler
599                             *handlers)
600 {
601   struct HandlerList *p;
602
603   p = GNUNET_malloc (sizeof (struct HandlerList));
604   p->handlers = handlers;
605   p->next = server->handlers;
606   server->handlers = p;
607 }
608
609
610 /**
611  * Task run to warn about missing calls to 'GNUNET_SERVER_receive_done'.
612  *
613  * @param cls our 'struct GNUNET_SERVER_Client*' to process more requests from
614  * @param tc scheduler context (unused)
615  */
616 static void
617 warn_no_receive_done (void *cls, 
618                       const struct GNUNET_SCHEDULER_TaskContext *tc)
619 {
620   struct GNUNET_SERVER_Client *client = cls;
621
622   client->warn_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
623                                                     &warn_no_receive_done,
624                                                     client);
625   if (0 == (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
626     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
627                 _("Processing code for message of type %u did not call GNUNET_SERVER_receive_done after %llums\n"),
628                 (unsigned int) client->warn_type,
629                 (unsigned long long) GNUNET_TIME_absolute_get_duration (client->warn_start).rel_value);
630 }
631
632
633 /**
634  * Disable the warning the server issues if a message is not acknowledged
635  * in a timely fashion.  Use this call if a client is intentionally delayed
636  * for a while.  Only applies to the current message.
637  *
638  * @param client client for which to disable the warning
639  */
640 void
641 GNUNET_SERVER_disable_receive_done_warning (struct GNUNET_SERVER_Client *client)
642 {
643   if (GNUNET_SCHEDULER_NO_TASK != client->warn_task)
644     {
645       GNUNET_SCHEDULER_cancel (client->warn_task);
646       client->warn_task = GNUNET_SCHEDULER_NO_TASK;
647     }
648 }
649
650
651 /**
652  * Inject a message into the server, pretend it came
653  * from the specified client.  Delivery of the message
654  * will happen instantly (if a handler is installed;
655  * otherwise the call does nothing).
656  *
657  * @param server the server receiving the message
658  * @param sender the "pretended" sender of the message
659  *        can be NULL!
660  * @param message message to transmit
661  * @return GNUNET_OK if the message was OK and the
662  *                   connection can stay open
663  *         GNUNET_SYSERR if the connection to the
664  *         client should be shut down
665  */
666 int
667 GNUNET_SERVER_inject (struct GNUNET_SERVER_Handle *server,
668                       struct GNUNET_SERVER_Client *sender,
669                       const struct GNUNET_MessageHeader *message)
670 {
671   struct HandlerList *pos;
672   const struct GNUNET_SERVER_MessageHandler *mh;
673   unsigned int i;
674   uint16_t type;
675   uint16_t size;
676   int found;
677
678   type = ntohs (message->type);
679   size = ntohs (message->size);
680 #if DEBUG_SERVER
681
682   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
683               "Server schedules transmission of %u-byte message of type %u to client.\n",
684               size, type);
685 #endif
686   pos = server->handlers;
687   found = GNUNET_NO;
688   while (pos != NULL)
689     {
690       i = 0;
691       while (pos->handlers[i].callback != NULL)
692         {
693           mh = &pos->handlers[i];
694           if ( (mh->type == type) ||
695                (mh->type == GNUNET_MESSAGE_TYPE_ALL) )
696             {
697               if ((mh->expected_size != 0) && (mh->expected_size != size))
698                 {
699 #if GNUNET8_NETWORK_IS_DEAD
700                   GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
701                               "Expected %u bytes for message of type %u, got %u\n",
702                               mh->expected_size,
703                               mh->type,
704                               size);
705                   GNUNET_break_op (0);
706 #endif
707                   return GNUNET_SYSERR;
708                 }
709               if (sender != NULL)
710                 {
711                   if (0 == sender->suspended)
712                     {
713                       sender->warn_start = GNUNET_TIME_absolute_get ();
714                       sender->warn_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
715                                                                         &warn_no_receive_done,
716                                                                         sender);
717                       sender->warn_type = type;
718                     }
719                   sender->suspended++;
720                 }
721               mh->callback (mh->callback_cls, sender, message);
722               found = GNUNET_YES;
723             }
724           i++;
725         }
726       pos = pos->next;
727     }
728   if (found == GNUNET_NO)
729     {
730       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
731                   "Received message of unknown type %d\n",
732                   type);
733       if (server->require_found == GNUNET_YES)
734         return GNUNET_SYSERR;
735     }
736   return GNUNET_OK;
737 }
738
739
740 /**
741  * We are receiving an incoming message.  Process it.
742  *
743  * @param cls our closure (handle for the client)
744  * @param buf buffer with data received from network
745  * @param available number of bytes available in buf
746  * @param addr address of the sender
747  * @param addrlen length of addr
748  * @param errCode code indicating errors receiving, 0 for success
749  */
750 static void
751 process_incoming (void *cls,
752                   const void *buf,
753                   size_t available,
754                   const struct sockaddr *addr, 
755                   socklen_t addrlen, int errCode);
756
757
758 /**
759  * Process messages from the client's message tokenizer until either
760  * the tokenizer is empty (and then schedule receiving more), or 
761  * until some handler is not immediately done (then wait for restart_processing)
762  * or shutdown.
763  *
764  * @param client the client to process, RC must have already been increased
765  *        using GNUNET_SERVER_client_keep and will be decreased by one in this
766  *        function
767  * @param ret GNUNET_NO to start processing from the buffer,
768  *            GNUNET_OK if the mst buffer is drained and we should instantly go back to receiving
769  *            GNUNET_SYSERR if we should instantly abort due to error in a previous step
770  */
771 static void
772 process_mst (struct GNUNET_SERVER_Client *client,
773              int ret)
774 {
775   while ( (ret != GNUNET_SYSERR) && 
776           (client->server != NULL) &&
777           (GNUNET_YES != client->shutdown_now) &&
778           (0 == client->suspended) )
779     {
780       if (ret == GNUNET_OK)
781         {
782           client->receive_pending = GNUNET_YES;
783 #if DEBUG_SERVER
784           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
785                       "Server re-enters receive loop, timeout: %llu.\n", client->idle_timeout.rel_value);
786 #endif
787           GNUNET_CONNECTION_receive (client->connection,
788                                      GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
789                                      client->idle_timeout,
790                                      &process_incoming, client);
791           break;
792         }
793 #if DEBUG_SERVER
794       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Server processes additional messages instantly.\n");
795 #endif
796       ret = GNUNET_SERVER_mst_receive (client->mst, client, NULL, 0, GNUNET_NO, GNUNET_YES);
797     }
798 #if DEBUG_SERVER
799   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
800               "Server leaves instant processing loop: ret = %d, server = %p, shutdown = %d, suspended = %u\n",
801               ret,
802               client->server,
803               client->shutdown_now,
804               client->suspended);
805 #endif
806
807   if (ret == GNUNET_NO)
808     {
809 #if DEBUG_SERVER
810       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
811                   "Server has more data pending but is suspended.\n");
812 #endif
813       client->receive_pending = GNUNET_SYSERR; /* data pending */
814     }
815   if ( (ret == GNUNET_SYSERR) ||
816        (GNUNET_YES == client->shutdown_now) )
817     GNUNET_SERVER_client_disconnect (client);
818   GNUNET_SERVER_client_drop (client);
819 }
820
821
822 /**
823  * We are receiving an incoming message.  Process it.
824  *
825  * @param cls our closure (handle for the client)
826  * @param buf buffer with data received from network
827  * @param available number of bytes available in buf
828  * @param addr address of the sender
829  * @param addrlen length of addr
830  * @param errCode code indicating errors receiving, 0 for success
831  */
832 static void
833 process_incoming (void *cls,
834                   const void *buf,
835                   size_t available,
836                   const struct sockaddr *addr, 
837                   socklen_t addrlen, int errCode)
838 {
839   struct GNUNET_SERVER_Client *client = cls;
840   struct GNUNET_SERVER_Handle *server = client->server;
841   struct GNUNET_TIME_Absolute end;
842   struct GNUNET_TIME_Absolute now;
843   int ret;
844
845   GNUNET_assert (client->receive_pending == GNUNET_YES);
846   client->receive_pending = GNUNET_NO;
847   now = GNUNET_TIME_absolute_get ();
848   end = GNUNET_TIME_absolute_add (client->last_activity,
849                                   client->idle_timeout);
850
851   if ( (buf == NULL) && (available == 0)  && (addr == NULL) && (errCode == 0) &&
852        (client->shutdown_now != GNUNET_YES) &&
853        (server != NULL) &&
854        (GNUNET_YES == GNUNET_CONNECTION_check (client->connection)) &&
855        (end.abs_value > now.abs_value) )
856     {
857       /* wait longer, timeout changed (i.e. due to us sending) */
858 #if DEBUG_SERVER
859       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
860                   "Receive time out, but no disconnect due to sending (%p)\n",
861                   GNUNET_a2s (addr, addrlen));
862 #endif
863       client->receive_pending = GNUNET_YES;
864       GNUNET_CONNECTION_receive (client->connection,
865                                  GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
866                                  GNUNET_TIME_absolute_get_remaining (end),
867                                  &process_incoming, client);
868       return;
869     }
870   if ((buf == NULL) ||
871       (available == 0) ||
872       (errCode != 0) ||
873       (server == NULL) ||
874       (client->shutdown_now == GNUNET_YES) ||
875       (GNUNET_YES != GNUNET_CONNECTION_check (client->connection)))
876     {
877       /* other side closed connection, error connecting, etc. */
878       GNUNET_SERVER_client_disconnect (client);
879       return;
880     }
881 #if DEBUG_SERVER
882   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
883               "Server receives %u bytes from `%s'.\n",
884               (unsigned int) available, 
885               GNUNET_a2s (addr, addrlen));
886 #endif
887   GNUNET_SERVER_client_keep (client);
888   client->last_activity = now;
889   ret = GNUNET_SERVER_mst_receive (client->mst, client, buf, available, GNUNET_NO, GNUNET_YES);
890   process_mst (client, ret);
891 }
892
893
894 /**
895  * Task run to start again receiving from the network
896  * and process requests.
897  *
898  * @param cls our 'struct GNUNET_SERVER_Client*' to process more requests from
899  * @param tc scheduler context (unused)
900  */
901 static void
902 restart_processing (void *cls, 
903                     const struct GNUNET_SCHEDULER_TaskContext *tc)
904 {
905   struct GNUNET_SERVER_Client *client = cls;
906   struct GNUNET_SERVER_Handle *server = client->server;
907
908   client->restart_task = GNUNET_SCHEDULER_NO_TASK;
909   if ( (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) &&
910        (GNUNET_NO == server->clients_ignore_shutdown) )
911     {
912       GNUNET_SERVER_client_disconnect (client);
913       return;
914     }  
915   if (client->receive_pending == GNUNET_NO)
916     {
917 #if DEBUG_SERVER
918       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
919                   "Server begins to read again from client.\n");
920 #endif
921       client->receive_pending = GNUNET_YES;
922       GNUNET_CONNECTION_receive (client->connection,
923                                  GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
924                                  client->idle_timeout, &process_incoming, client);
925       return;
926     }
927 #if DEBUG_SERVER
928   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
929               "Server continues processing messages still in the buffer.\n");
930 #endif
931   GNUNET_SERVER_client_keep (client);
932   client->receive_pending = GNUNET_NO;
933   process_mst (client, GNUNET_NO);
934 }
935
936
937 /**
938  * This function is called whenever our inbound message tokenizer has
939  * received a complete message.
940  *
941  * @param cls closure (struct GNUNET_SERVER_Handle)
942  * @param client identification of the client (struct GNUNET_SERVER_Client*)
943  * @param message the actual message
944  */
945 static void
946 client_message_tokenizer_callback (void *cls,
947                                    void *client,
948                                    const struct GNUNET_MessageHeader *message)
949 {
950   struct GNUNET_SERVER_Handle *server = cls;
951   struct GNUNET_SERVER_Client *sender = client;
952   int ret;
953
954 #if DEBUG_SERVER
955
956   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
957               "Tokenizer gives server message of type %u from client\n",
958               ntohs (message->type));
959 #endif
960   sender->in_process_client_buffer = GNUNET_YES;
961   ret = GNUNET_SERVER_inject (server, sender, message);
962   sender->in_process_client_buffer = GNUNET_NO;
963   if (GNUNET_OK != ret)
964     GNUNET_SERVER_client_disconnect (sender); 
965 }
966
967
968 /**
969  * Add a TCP socket-based connection to the set of handles managed by
970  * this server.  Use this function for outgoing (P2P) connections that
971  * we initiated (and where this server should process incoming
972  * messages).
973  *
974  * @param server the server to use
975  * @param connection the connection to manage (client must
976  *        stop using this connection from now on)
977  * @return the client handle (client should call
978  *         "client_drop" on the return value eventually)
979  */
980 struct GNUNET_SERVER_Client *
981 GNUNET_SERVER_connect_socket (struct
982                               GNUNET_SERVER_Handle
983                               *server,
984                               struct GNUNET_CONNECTION_Handle *connection)
985 {
986   struct GNUNET_SERVER_Client *client;
987
988   client = GNUNET_malloc (sizeof (struct GNUNET_SERVER_Client));
989   client->connection = connection;
990   client->mst = GNUNET_SERVER_mst_create (&client_message_tokenizer_callback,
991                                           server);
992   client->reference_count = 1;
993   client->server = server;
994   client->last_activity = GNUNET_TIME_absolute_get ();
995   client->next = server->clients;
996   client->idle_timeout = server->idle_timeout;
997   server->clients = client;
998   client->receive_pending = GNUNET_YES;
999   client->callback = NULL;
1000   client->callback_cls = NULL;
1001   GNUNET_CONNECTION_receive (client->connection,
1002                              GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
1003                              client->idle_timeout, &process_incoming, client);
1004   return client;
1005 }
1006
1007
1008 /**
1009  * Change the timeout for a particular client.  Decreasing the timeout
1010  * may not go into effect immediately (only after the previous timeout
1011  * times out or activity happens on the socket).
1012  *
1013  * @param client the client to update
1014  * @param timeout new timeout for activities on the socket
1015  */
1016 void
1017 GNUNET_SERVER_client_set_timeout (struct GNUNET_SERVER_Client *client,
1018          struct GNUNET_TIME_Relative timeout)
1019 {
1020   client->idle_timeout = timeout;
1021 }
1022
1023
1024 /**
1025  * Notify the server that the given client handle should
1026  * be kept (keeps the connection up if possible, increments
1027  * the internal reference counter).
1028  *
1029  * @param client the client to keep
1030  */
1031 void
1032 GNUNET_SERVER_client_keep (struct GNUNET_SERVER_Client *client)
1033 {
1034   client->reference_count++;
1035 }
1036
1037
1038 /**
1039  * Notify the server that the given client handle is no
1040  * longer required.  Decrements the reference counter.  If
1041  * that counter reaches zero an inactive connection maybe
1042  * closed.
1043  *
1044  * @param client the client to drop
1045  */
1046 void
1047 GNUNET_SERVER_client_drop (struct GNUNET_SERVER_Client *client)
1048 {
1049   GNUNET_assert (client->reference_count > 0);
1050   client->reference_count--;
1051   if ( (client->shutdown_now == GNUNET_YES) && 
1052        (client->reference_count == 0) )
1053     GNUNET_SERVER_client_disconnect (client);
1054 }
1055
1056
1057 /**
1058  * Obtain the network address of the other party.
1059  *
1060  * @param client the client to get the address for
1061  * @param addr where to store the address
1062  * @param addrlen where to store the length of the address
1063  * @return GNUNET_OK on success
1064  */
1065 int
1066 GNUNET_SERVER_client_get_address (struct GNUNET_SERVER_Client *client,
1067                                   void **addr, size_t * addrlen)
1068 {
1069   return GNUNET_CONNECTION_get_address (client->connection,
1070                                         addr, addrlen);
1071 }
1072
1073
1074 /**
1075  * Ask the server to notify us whenever a client disconnects.
1076  * This function is called whenever the actual network connection
1077  * is closed; the reference count may be zero or larger than zero
1078  * at this point.
1079  *
1080  * @param server the server manageing the clients
1081  * @param callback function to call on disconnect
1082  * @param callback_cls closure for callback
1083  */
1084 void
1085 GNUNET_SERVER_disconnect_notify (struct GNUNET_SERVER_Handle *server,
1086                                  GNUNET_SERVER_DisconnectCallback callback,
1087                                  void *callback_cls)
1088 {
1089   struct NotifyList *n;
1090
1091   n = GNUNET_malloc (sizeof (struct NotifyList));
1092   n->callback = callback;
1093   n->callback_cls = callback_cls;
1094   n->next = server->disconnect_notify_list;
1095   server->disconnect_notify_list = n;
1096 }
1097
1098
1099 /**
1100  * Ask the server to stop notifying us whenever a client disconnects.
1101  *
1102  * @param server the server manageing the clients
1103  * @param callback function to call on disconnect
1104  * @param callback_cls closure for callback
1105  */
1106 void
1107 GNUNET_SERVER_disconnect_notify_cancel (struct GNUNET_SERVER_Handle *server,
1108                                         GNUNET_SERVER_DisconnectCallback callback,
1109                                         void *callback_cls)
1110 {
1111   struct NotifyList *pos;
1112   struct NotifyList *prev;
1113
1114   prev = NULL;
1115   pos = server->disconnect_notify_list;
1116   while (pos != NULL)
1117     {
1118       if ( (pos->callback == callback) &&
1119            (pos->callback_cls == callback_cls ) )
1120         break;
1121       prev = pos;
1122       pos = pos->next;
1123     }
1124   if (pos == NULL)
1125     {
1126       GNUNET_break (0);
1127       return;
1128     }
1129   if (prev == NULL)
1130     server->disconnect_notify_list = pos->next;
1131   else
1132     prev->next = pos->next;
1133   GNUNET_free (pos);
1134 }
1135
1136
1137 /**
1138  * Ask the server to disconnect from the given client.
1139  * This is the same as returning GNUNET_SYSERR from a message
1140  * handler, except that it allows dropping of a client even
1141  * when not handling a message from that client.
1142  *
1143  * @param client the client to disconnect from
1144  */
1145 void
1146 GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client)
1147 {
1148   struct GNUNET_SERVER_Client *prev;
1149   struct GNUNET_SERVER_Client *pos;
1150   struct GNUNET_SERVER_Handle *server;
1151   struct NotifyList *n;
1152   unsigned int rc;
1153
1154 #if DEBUG_SERVER
1155   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1156               "Client is being disconnected from the server.\n");
1157 #endif
1158   if (client->restart_task != GNUNET_SCHEDULER_NO_TASK)
1159     {
1160       GNUNET_SCHEDULER_cancel (client->restart_task);
1161       client->restart_task = GNUNET_SCHEDULER_NO_TASK;
1162     }
1163   if (client->warn_task != GNUNET_SCHEDULER_NO_TASK)
1164     {
1165       GNUNET_SCHEDULER_cancel (client->warn_task);
1166       client->warn_task = GNUNET_SCHEDULER_NO_TASK;
1167     }
1168   if (GNUNET_YES == client->receive_pending)
1169     {
1170       GNUNET_CONNECTION_receive_cancel (client->connection);
1171       client->receive_pending = GNUNET_NO;
1172     }
1173
1174   rc = client->reference_count;  
1175   if (client->server != NULL)
1176     {
1177       server = client->server;
1178       client->server = NULL;
1179       client->shutdown_now = GNUNET_YES;
1180       prev = NULL;
1181       pos = server->clients;
1182       while ((pos != NULL) && (pos != client))
1183         {
1184           prev = pos;
1185           pos = pos->next;
1186         }
1187       GNUNET_assert (pos != NULL);
1188       if (prev == NULL)
1189         server->clients = pos->next;
1190       else
1191         prev->next = pos->next;
1192       if (client->restart_task != GNUNET_SCHEDULER_NO_TASK)
1193         {
1194           GNUNET_SCHEDULER_cancel (client->restart_task);
1195           client->restart_task = GNUNET_SCHEDULER_NO_TASK;
1196         }
1197       if (client->warn_task != GNUNET_SCHEDULER_NO_TASK)
1198         {
1199           GNUNET_SCHEDULER_cancel (client->warn_task);
1200           client->warn_task = GNUNET_SCHEDULER_NO_TASK;
1201         }
1202       n = server->disconnect_notify_list;
1203       while (n != NULL)
1204         {
1205           n->callback (n->callback_cls, client);
1206           n = n->next;
1207         }
1208     }
1209   if (rc > 0)
1210     {
1211 #if DEBUG_SERVER
1212       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1213                   "RC still positive, not destroying everything.\n");
1214 #endif
1215       return;
1216     }
1217   if (client->in_process_client_buffer == GNUNET_YES)
1218     {
1219 #if DEBUG_SERVER
1220       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1221                   "Still processing inputs, not destroying everything.\n");
1222 #endif
1223       return;
1224     }
1225
1226   if (client->persist == GNUNET_YES)
1227     GNUNET_CONNECTION_persist_ (client->connection);  
1228   GNUNET_CONNECTION_destroy (client->connection, GNUNET_NO);
1229   GNUNET_SERVER_mst_destroy (client->mst);
1230   GNUNET_free (client);  
1231 }
1232
1233
1234 /**
1235  * Disable the "CORK" feature for communication with the given client,
1236  * forcing the OS to immediately flush the buffer on transmission
1237  * instead of potentially buffering multiple messages.
1238  *
1239  * @param client handle to the client
1240  * @return GNUNET_OK on success
1241  */
1242 int
1243 GNUNET_SERVER_client_disable_corking (struct GNUNET_SERVER_Client *client)
1244 {
1245   return GNUNET_CONNECTION_disable_corking (client->connection);
1246 }
1247
1248
1249 /**
1250  * Wrapper for transmission notification that calls the original
1251  * callback and update the last activity time for our connection.
1252  * 
1253  * @param cls the 'struct GNUNET_SERVER_Client'
1254  * @param size number of bytes we can transmit
1255  * @param buf where to copy the message 
1256  * @return number of bytes actually transmitted
1257  */
1258 static size_t 
1259 transmit_ready_callback_wrapper (void *cls, size_t size, void *buf)
1260 {
1261   struct GNUNET_SERVER_Client *client = cls;
1262   size_t ret;
1263
1264   ret = client->callback (client->callback_cls, size, buf);
1265   if (ret > 0)
1266     client->last_activity = GNUNET_TIME_absolute_get();
1267   return ret;
1268 }
1269
1270
1271 /**
1272  * Notify us when the server has enough space to transmit
1273  * a message of the given size to the given client.
1274  *
1275  * @param client client to transmit message to
1276  * @param size requested amount of buffer space
1277  * @param timeout after how long should we give up (and call
1278  *        notify with buf NULL and size 0)?
1279  * @param callback function to call when space is available
1280  * @param callback_cls closure for callback
1281  * @return non-NULL if the notify callback was queued; can be used
1282  *           to cancel the request using
1283  *           GNUNET_CONNECTION_notify_transmit_ready_cancel.
1284  *         NULL if we are already going to notify someone else (busy)
1285  */
1286 struct GNUNET_CONNECTION_TransmitHandle *
1287 GNUNET_SERVER_notify_transmit_ready (struct GNUNET_SERVER_Client *client,
1288                                      size_t size,
1289                                      struct GNUNET_TIME_Relative timeout,
1290                                      GNUNET_CONNECTION_TransmitReadyNotify
1291                                      callback, void *callback_cls)
1292 {
1293   client->callback_cls = callback_cls;
1294   client->callback = callback;
1295   return GNUNET_CONNECTION_notify_transmit_ready (client->connection,
1296                                                   size,
1297                                                   timeout,
1298                                                   &transmit_ready_callback_wrapper, client);
1299 }
1300
1301
1302 /**
1303  * Set the persistent flag on this client, used to setup client connection
1304  * to only be killed when the service it's connected to is actually dead.
1305  *
1306  * @param client the client to set the persistent flag on
1307  */
1308 void
1309 GNUNET_SERVER_client_persist_ (struct GNUNET_SERVER_Client *client)
1310 {
1311   client->persist = GNUNET_YES;
1312 }
1313
1314
1315 /**
1316  * Resume receiving from this client, we are done processing the
1317  * current request.  This function must be called from within each
1318  * GNUNET_SERVER_MessageCallback (or its respective continuations).
1319  *
1320  * @param client client we were processing a message of
1321  * @param success GNUNET_OK to keep the connection open and
1322  *                          continue to receive
1323  *                GNUNET_NO to close the connection (normal behavior)
1324  *                GNUNET_SYSERR to close the connection (signal
1325  *                          serious error)
1326  */
1327 void
1328 GNUNET_SERVER_receive_done (struct GNUNET_SERVER_Client *client, int success)
1329 {
1330   if (client == NULL)
1331     return;
1332   GNUNET_assert (client->suspended > 0);
1333   client->suspended--;
1334   if (success != GNUNET_OK)
1335     {
1336 #if DEBUG_SERVER
1337       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1338                   "GNUNET_SERVER_receive_done called with failure indication\n");
1339 #endif
1340       GNUNET_SERVER_client_disconnect (client);
1341       return;
1342     }
1343   if (client->suspended > 0)
1344     {
1345 #if DEBUG_SERVER
1346       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1347                   "GNUNET_SERVER_receive_done called, but more clients pending\n");
1348 #endif
1349       return;
1350     }
1351   if (GNUNET_SCHEDULER_NO_TASK != client->warn_task)
1352     {
1353       GNUNET_SCHEDULER_cancel (client->warn_task);
1354       client->warn_task = GNUNET_SCHEDULER_NO_TASK;
1355     }
1356   if (client->in_process_client_buffer == GNUNET_YES)
1357     {
1358 #if DEBUG_SERVER
1359       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1360                   "GNUNET_SERVER_receive_done called while still in processing loop\n");
1361 #endif
1362       return;
1363     }
1364   if (client->server == NULL)
1365     {
1366       GNUNET_SERVER_client_disconnect (client);
1367       return;
1368     }
1369 #if DEBUG_SERVER
1370   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1371               "GNUNET_SERVER_receive_done causes restart in reading from the socket\n");
1372 #endif
1373   GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == client->restart_task);
1374   client->restart_task = GNUNET_SCHEDULER_add_now (&restart_processing,
1375                                                    client);
1376 }
1377
1378
1379 /**
1380  * Configure this server's connections to continue handling client
1381  * requests as usual even after we get a shutdown signal.  The change
1382  * only applies to clients that connect to the server from the outside
1383  * using TCP after this call.  Clients managed previously or those
1384  * added using GNUNET_SERVER_connect_socket and
1385  * GNUNET_SERVER_connect_callback are not affected by this option.
1386  *
1387  * @param h server handle
1388  * @param do_ignore GNUNET_YES to ignore, GNUNET_NO to restore default
1389  */
1390 void
1391 GNUNET_SERVER_ignore_shutdown (struct GNUNET_SERVER_Handle *h, int do_ignore)
1392 {
1393   h->clients_ignore_shutdown = do_ignore;
1394 }
1395
1396 /* end of server.c */