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