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