glitch in the license text detected by hyazinthe, thank you!
[oweals/gnunet.git] / src / transport / tcp_server_legacy.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2009-2013 GNUnet e.V.
4
5      GNUnet is free software: you can redistribute it and/or modify it
6      under the terms of the GNU Affero General Public License as published
7      by the Free Software Foundation, either version 3 of the License,
8      or (at your 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      Affero General Public License for more details.
14 */
15
16 /**
17  * @file util/server.c
18  * @brief library for building GNUnet network servers
19  * @author Christian Grothoff
20  */
21
22 #include "platform.h"
23 #include "gnunet_util_lib.h"
24 #include "gnunet_protocols.h"
25
26 #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util-server", syscall, filename)
27
28
29 /**
30  * List of arrays of message handlers.
31  */
32 struct HandlerList
33 {
34   /**
35    * This is a linked list.
36    */
37   struct HandlerList *next;
38
39   /**
40    * NULL-terminated array of handlers.
41    */
42   const struct GNUNET_SERVER_MessageHandler *handlers;
43 };
44
45
46 /**
47  * List of arrays of message handlers.
48  */
49 struct NotifyList
50 {
51   /**
52    * This is a doubly linked list.
53    */
54   struct NotifyList *next;
55
56   /**
57    * This is a doubly linked list.
58    */
59   struct NotifyList *prev;
60
61   /**
62    * Function to call.
63    */
64   GNUNET_SERVER_DisconnectCallback callback;
65
66   /**
67    * Closure for callback.
68    */
69   void *callback_cls;
70 };
71
72
73 /**
74  * @brief handle for a server
75  */
76 struct GNUNET_SERVER_Handle
77 {
78   /**
79    * List of handlers for incoming messages.
80    */
81   struct HandlerList *handlers;
82
83   /**
84    * Head of list of our current clients.
85    */
86   struct GNUNET_SERVER_Client *clients_head;
87
88   /**
89    * Head of list of our current clients.
90    */
91   struct GNUNET_SERVER_Client *clients_tail;
92
93   /**
94    * Head of linked list of functions to call on disconnects by clients.
95    */
96   struct NotifyList *disconnect_notify_list_head;
97
98   /**
99    * Tail of linked list of functions to call on disconnects by clients.
100    */
101   struct NotifyList *disconnect_notify_list_tail;
102
103   /**
104    * Head of linked list of functions to call on connects by clients.
105    */
106   struct NotifyList *connect_notify_list_head;
107
108   /**
109    * Tail of linked list of functions to call on connects by clients.
110    */
111   struct NotifyList *connect_notify_list_tail;
112
113   /**
114    * Function to call for access control.
115    */
116   GNUNET_CONNECTION_AccessCheck access_cb;
117
118   /**
119    * Closure for @e access_cb.
120    */
121   void *access_cb_cls;
122
123   /**
124    * NULL-terminated array of sockets used to listen for new
125    * connections.
126    */
127   struct GNUNET_NETWORK_Handle **listen_sockets;
128
129   /**
130    * After how long should an idle connection time
131    * out (on write).
132    */
133   struct GNUNET_TIME_Relative idle_timeout;
134
135   /**
136    * Task scheduled to do the listening.
137    */
138   struct GNUNET_SCHEDULER_Task * listen_task;
139
140   /**
141    * Alternative function to create a MST instance.
142    */
143   GNUNET_SERVER_MstCreateCallback mst_create;
144
145   /**
146    * Alternative function to destroy a MST instance.
147    */
148   GNUNET_SERVER_MstDestroyCallback mst_destroy;
149
150   /**
151    * Alternative function to give data to a MST instance.
152    */
153   GNUNET_SERVER_MstReceiveCallback mst_receive;
154
155   /**
156    * Closure for 'mst_'-callbacks.
157    */
158   void *mst_cls;
159
160   /**
161    * Do we ignore messages of types that we do not understand or do we
162    * require that a handler is found (and if not kill the connection)?
163    */
164   int require_found;
165
166   /**
167    * Set to #GNUNET_YES once we are in 'soft' shutdown where we wait for
168    * all non-monitor clients to disconnect before we call
169    * #GNUNET_SERVER_destroy.  See test_monitor_clients().  Set to
170    * #GNUNET_SYSERR once the final destroy task has been scheduled
171    * (we cannot run it in the same task).
172    */
173   int in_soft_shutdown;
174 };
175
176
177 /**
178  * Handle server returns for aborting transmission to a client.
179  */
180 struct GNUNET_SERVER_TransmitHandle
181 {
182   /**
183    * Function to call to get the message.
184    */
185   GNUNET_CONNECTION_TransmitReadyNotify callback;
186
187   /**
188    * Closure for @e callback
189    */
190   void *callback_cls;
191
192   /**
193    * Active connection transmission handle.
194    */
195   struct GNUNET_CONNECTION_TransmitHandle *cth;
196
197 };
198
199
200 /**
201  * @brief handle for a client of the server
202  */
203 struct GNUNET_SERVER_Client
204 {
205
206   /**
207    * This is a doubly linked list.
208    */
209   struct GNUNET_SERVER_Client *next;
210
211   /**
212    * This is a doubly linked list.
213    */
214   struct GNUNET_SERVER_Client *prev;
215
216   /**
217    * Processing of incoming data.
218    */
219   void *mst;
220
221   /**
222    * Server that this client belongs to.
223    */
224   struct GNUNET_SERVER_Handle *server;
225
226   /**
227    * Client closure for callbacks.
228    */
229   struct GNUNET_CONNECTION_Handle *connection;
230
231   /**
232    * User context value, manipulated using
233    * 'GNUNET_SERVER_client_{get/set}_user_context' functions.
234    */
235   void *user_context;
236
237   /**
238    * ID of task used to restart processing.
239    */
240   struct GNUNET_SCHEDULER_Task * restart_task;
241
242   /**
243    * Task that warns about missing calls to #GNUNET_SERVER_receive_done.
244    */
245   struct GNUNET_SCHEDULER_Task * warn_task;
246
247   /**
248    * Time when the warn task was started.
249    */
250   struct GNUNET_TIME_Absolute warn_start;
251
252   /**
253    * Last activity on this socket (used to time it out
254    * if reference_count == 0).
255    */
256   struct GNUNET_TIME_Absolute last_activity;
257
258   /**
259    * Transmission handle we return for this client from
260    * #GNUNET_SERVER_notify_transmit_ready.
261    */
262   struct GNUNET_SERVER_TransmitHandle th;
263
264   /**
265    * After how long should an idle connection time
266    * out (on write).
267    */
268   struct GNUNET_TIME_Relative idle_timeout;
269
270   /**
271    * Number of external entities with a reference to
272    * this client object.
273    */
274   unsigned int reference_count;
275
276   /**
277    * Was processing if incoming messages suspended while
278    * we were still processing data already received?
279    * This is a counter saying how often processing was
280    * suspended (once per handler invoked).
281    */
282   unsigned int suspended;
283
284   /**
285    * Last size given when user context was initialized; used for
286    * sanity check.
287    */
288   size_t user_context_size;
289
290   /**
291    * Are we currently in the "process_client_buffer" function (and
292    * will hence restart the receive job on exit if suspended == 0 once
293    * we are done?).  If this is set, then "receive_done" will
294    * essentially only decrement suspended; if this is not set, then
295    * "receive_done" may need to restart the receive process (either
296    * from the side-buffer or via select/recv).
297    */
298   int in_process_client_buffer;
299
300   /**
301    * We're about to close down this client.
302    */
303   int shutdown_now;
304
305   /**
306    * Are we currently trying to receive? (#GNUNET_YES if we are,
307    * #GNUNET_NO if we are not, #GNUNET_SYSERR if data is already
308    * available in MST).
309    */
310   int receive_pending;
311
312   /**
313    * Persist the file handle for this client no matter what happens,
314    * force the OS to close once the process actually dies.  Should only
315    * be used in special cases!
316    */
317   int persist;
318
319   /**
320    * Is this client a 'monitor' client that should not be counted
321    * when deciding on destroying the server during soft shutdown?
322    * (see also #GNUNET_SERVICE_start)
323    */
324   int is_monitor;
325
326   /**
327    * Type of last message processed (for warn_no_receive_done).
328    */
329   uint16_t warn_type;
330 };
331
332
333
334 /**
335  * Return user context associated with the given client.
336  * Note: you should probably use the macro (call without the underscore).
337  *
338  * @param client client to query
339  * @param size number of bytes in user context struct (for verification only)
340  * @return pointer to user context
341  */
342 void *
343 GNUNET_SERVER_client_get_user_context_ (struct GNUNET_SERVER_Client *client,
344                                         size_t size)
345 {
346   if ((0 == client->user_context_size) &&
347       (NULL == client->user_context))
348     return NULL; /* never set */
349   GNUNET_assert (size == client->user_context_size);
350   return client->user_context;
351 }
352
353
354 /**
355  * Set user context to be associated with the given client.
356  * Note: you should probably use the macro (call without the underscore).
357  *
358  * @param client client to query
359  * @param ptr pointer to user context
360  * @param size number of bytes in user context struct (for verification only)
361  */
362 void
363 GNUNET_SERVER_client_set_user_context_ (struct GNUNET_SERVER_Client *client,
364                                         void *ptr,
365                                         size_t size)
366 {
367   if (NULL == ptr)
368   {
369     client->user_context_size = 0;
370     client->user_context = ptr;
371     return;
372   }
373   client->user_context_size = size;
374   client->user_context = ptr;
375 }
376
377
378 /**
379  * Scheduler says our listen socket is ready.  Process it!
380  *
381  * @param cls handle to our server for which we are processing the listen
382  *        socket
383  */
384 static void
385 process_listen_socket (void *cls)
386 {
387   struct GNUNET_SERVER_Handle *server = cls;
388   const struct GNUNET_SCHEDULER_TaskContext *tc;
389   struct GNUNET_CONNECTION_Handle *sock;
390   unsigned int i;
391
392   server->listen_task = NULL;
393   tc = GNUNET_SCHEDULER_get_task_context ();
394   for (i = 0; NULL != server->listen_sockets[i]; i++)
395   {
396     if (GNUNET_NETWORK_fdset_isset (tc->read_ready,
397                                     server->listen_sockets[i]))
398     {
399       sock =
400           GNUNET_CONNECTION_create_from_accept (server->access_cb,
401                                                 server->access_cb_cls,
402                                                 server->listen_sockets[i]);
403       if (NULL != sock)
404       {
405         LOG (GNUNET_ERROR_TYPE_DEBUG,
406              "Server accepted incoming connection.\n");
407         (void) GNUNET_SERVER_connect_socket (server,
408                                              sock);
409       }
410     }
411   }
412   /* listen for more! */
413   GNUNET_SERVER_resume (server);
414 }
415
416
417 /**
418  * Create and initialize a listen socket for the server.
419  *
420  * @param server_addr address to listen on
421  * @param socklen length of @a server_addr
422  * @return NULL on error, otherwise the listen socket
423  */
424 static struct GNUNET_NETWORK_Handle *
425 open_listen_socket (const struct sockaddr *server_addr,
426                     socklen_t socklen)
427 {
428   struct GNUNET_NETWORK_Handle *sock;
429   uint16_t port;
430   int eno;
431
432   switch (server_addr->sa_family)
433   {
434   case AF_INET:
435     port = ntohs (((const struct sockaddr_in *) server_addr)->sin_port);
436     break;
437   case AF_INET6:
438     port = ntohs (((const struct sockaddr_in6 *) server_addr)->sin6_port);
439     break;
440   case AF_UNIX:
441     port = 0;
442     break;
443   default:
444     GNUNET_break (0);
445     port = 0;
446     break;
447   }
448   sock = GNUNET_NETWORK_socket_create (server_addr->sa_family, SOCK_STREAM, 0);
449   if (NULL == sock)
450   {
451     LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket");
452     errno = 0;
453     return NULL;
454   }
455   /* bind the socket */
456   if (GNUNET_OK != GNUNET_NETWORK_socket_bind (sock, server_addr, socklen))
457   {
458     eno = errno;
459     if (EADDRINUSE != errno)
460     {
461       /* we don't log 'EADDRINUSE' here since an IPv4 bind may
462        * fail if we already took the port on IPv6; if both IPv4 and
463        * IPv6 binds fail, then our caller will log using the
464        * errno preserved in 'eno' */
465       LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
466                     "bind");
467       if (0 != port)
468         LOG (GNUNET_ERROR_TYPE_ERROR,
469              _("`%s' failed for port %d (%s).\n"),
470              "bind",
471              port,
472              (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
473       eno = 0;
474     }
475     else
476     {
477       if (0 != port)
478         LOG (GNUNET_ERROR_TYPE_WARNING,
479              _("`%s' failed for port %d (%s): address already in use\n"),
480              "bind", port,
481              (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
482       else if (AF_UNIX == server_addr->sa_family)
483       {
484         LOG (GNUNET_ERROR_TYPE_WARNING,
485              _("`%s' failed for `%s': address already in use\n"),
486              "bind",
487              GNUNET_a2s (server_addr, socklen));
488       }
489     }
490     GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
491     errno = eno;
492     return NULL;
493   }
494   if (GNUNET_OK != GNUNET_NETWORK_socket_listen (sock, 5))
495   {
496     LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
497                   "listen");
498     GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
499     errno = 0;
500     return NULL;
501   }
502   if (0 != port)
503     LOG (GNUNET_ERROR_TYPE_DEBUG,
504          "Server starts to listen on port %u.\n",
505          port);
506   return sock;
507 }
508
509
510 /**
511  * Create a new server.
512  *
513  * @param access_cb function for access control
514  * @param access_cb_cls closure for @a access_cb
515  * @param lsocks NULL-terminated array of listen sockets
516  * @param idle_timeout after how long should we timeout idle connections?
517  * @param require_found if #GNUNET_YES, connections sending messages of unknown type
518  *        will be closed
519  * @return handle for the new server, NULL on error
520  *         (typically, "port" already in use)
521  */
522 struct GNUNET_SERVER_Handle *
523 GNUNET_SERVER_create_with_sockets (GNUNET_CONNECTION_AccessCheck access_cb,
524                                    void *access_cb_cls,
525                                    struct GNUNET_NETWORK_Handle **lsocks,
526                                    struct GNUNET_TIME_Relative idle_timeout,
527                                    int require_found)
528 {
529   struct GNUNET_SERVER_Handle *server;
530
531   server = GNUNET_new (struct GNUNET_SERVER_Handle);
532   server->idle_timeout = idle_timeout;
533   server->listen_sockets = lsocks;
534   server->access_cb = access_cb;
535   server->access_cb_cls = access_cb_cls;
536   server->require_found = require_found;
537   if (NULL != lsocks)
538     GNUNET_SERVER_resume (server);
539   return server;
540 }
541
542
543 /**
544  * Create a new server.
545  *
546  * @param access_cb function for access control
547  * @param access_cb_cls closure for @a access_cb
548  * @param server_addr address to listen on (including port), NULL terminated array
549  * @param socklen length of server_addr
550  * @param idle_timeout after how long should we timeout idle connections?
551  * @param require_found if YES, connections sending messages of unknown type
552  *        will be closed
553  * @return handle for the new server, NULL on error
554  *         (typically, "port" already in use)
555  */
556 struct GNUNET_SERVER_Handle *
557 GNUNET_SERVER_create (GNUNET_CONNECTION_AccessCheck access_cb,
558                       void *access_cb_cls,
559                       struct sockaddr *const *server_addr,
560                       const socklen_t * socklen,
561                       struct GNUNET_TIME_Relative idle_timeout,
562                       int require_found)
563 {
564   struct GNUNET_NETWORK_Handle **lsocks;
565   unsigned int i;
566   unsigned int j;
567   unsigned int k;
568   int seen;
569
570   i = 0;
571   while (NULL != server_addr[i])
572     i++;
573   if (i > 0)
574   {
575     lsocks = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (i + 1));
576     i = 0;
577     j = 0;
578     while (NULL != server_addr[i])
579     {
580       seen = 0;
581       for (k=0;k<i;k++)
582         if ( (socklen[k] == socklen[i]) &&
583              (0 == memcmp (server_addr[k], server_addr[i], socklen[i])) )
584         {
585           seen = 1;
586           break;
587         }
588       if (0 != seen)
589       {
590         /* duplicate address, skip */
591         i++;
592         continue;
593       }
594       lsocks[j] = open_listen_socket (server_addr[i], socklen[i]);
595       if (NULL != lsocks[j])
596         j++;
597       i++;
598     }
599     if (0 == j)
600     {
601       if (0 != errno)
602         LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "bind");
603       GNUNET_free (lsocks);
604       lsocks = NULL;
605     }
606   }
607   else
608   {
609     lsocks = NULL;
610   }
611   return GNUNET_SERVER_create_with_sockets (access_cb,
612                                             access_cb_cls,
613                                             lsocks,
614                                             idle_timeout,
615                                             require_found);
616 }
617
618
619 /**
620  * Set the 'monitor' flag on this client.  Clients which have been
621  * marked as 'monitors' won't prevent the server from shutting down
622  * once '#GNUNET_SERVER_stop_listening()' has been invoked.  The idea is
623  * that for "normal" clients we likely want to allow them to process
624  * their requests; however, monitor-clients are likely to 'never'
625  * disconnect during shutdown and thus will not be considered when
626  * determining if the server should continue to exist after
627  * #GNUNET_SERVER_destroy() has been called.
628  *
629  * @param client the client to set the 'monitor' flag on
630  */
631 void
632 GNUNET_SERVER_client_mark_monitor (struct GNUNET_SERVER_Client *client)
633 {
634   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
635               "Marking client as monitor!\n");
636   client->is_monitor = GNUNET_YES;
637 }
638
639
640 /**
641  * Helper function for #test_monitor_clients() to trigger
642  * #GNUNET_SERVER_destroy() after the stack has unwound.
643  *
644  * @param cls the `struct GNUNET_SERVER_Handle *` to destroy
645  */
646 static void
647 do_destroy (void *cls)
648 {
649   struct GNUNET_SERVER_Handle *server = cls;
650
651   GNUNET_SERVER_destroy (server);
652 }
653
654
655 /**
656  * Check if only 'monitor' clients are left.  If so, destroy the
657  * server completely.
658  *
659  * @param server server to test for full shutdown
660  */
661 static void
662 test_monitor_clients (struct GNUNET_SERVER_Handle *server)
663 {
664   struct GNUNET_SERVER_Client *client;
665
666   if (GNUNET_YES != server->in_soft_shutdown)
667     return;
668   for (client = server->clients_head; NULL != client; client = client->next)
669     if (GNUNET_NO == client->is_monitor)
670       return; /* not done yet */
671   server->in_soft_shutdown = GNUNET_SYSERR;
672   (void) GNUNET_SCHEDULER_add_now (&do_destroy, server);
673 }
674
675
676 /**
677  * Suspend accepting connections from the listen socket temporarily.
678  *
679  * @param server server to stop accepting connections.
680  */
681 void
682 GNUNET_SERVER_suspend (struct GNUNET_SERVER_Handle *server)
683 {
684   if (NULL != server->listen_task)
685   {
686     GNUNET_SCHEDULER_cancel (server->listen_task);
687     server->listen_task = NULL;
688   }
689 }
690
691
692 /**
693  * Resume accepting connections from the listen socket.
694  *
695  * @param server server to stop accepting connections.
696  */
697 void
698 GNUNET_SERVER_resume (struct GNUNET_SERVER_Handle *server)
699 {
700   struct GNUNET_NETWORK_FDSet *r;
701   unsigned int i;
702
703   if (NULL == server->listen_sockets)
704     return;
705   if (NULL == server->listen_sockets[0])
706     return; /* nothing to do, no listen sockets! */
707   if (NULL == server->listen_sockets[1])
708   {
709     /* simplified method: no fd set needed; this is then much simpler
710        and much more efficient */
711     server->listen_task =
712       GNUNET_SCHEDULER_add_read_net_with_priority (GNUNET_TIME_UNIT_FOREVER_REL,
713                                                    GNUNET_SCHEDULER_PRIORITY_HIGH,
714                                                    server->listen_sockets[0],
715                                                    &process_listen_socket, server);
716     return;
717   }
718   r = GNUNET_NETWORK_fdset_create ();
719   i = 0;
720   while (NULL != server->listen_sockets[i])
721     GNUNET_NETWORK_fdset_set (r, server->listen_sockets[i++]);
722   server->listen_task =
723     GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH,
724                                  GNUNET_TIME_UNIT_FOREVER_REL, r, NULL,
725                                  &process_listen_socket, server);
726   GNUNET_NETWORK_fdset_destroy (r);
727 }
728
729
730 /**
731  * Stop the listen socket and get ready to shutdown the server
732  * once only 'monitor' clients are left.
733  *
734  * @param server server to stop listening on
735  */
736 void
737 GNUNET_SERVER_stop_listening (struct GNUNET_SERVER_Handle *server)
738 {
739   unsigned int i;
740
741   LOG (GNUNET_ERROR_TYPE_DEBUG,
742        "Server in soft shutdown\n");
743   if (NULL != server->listen_task)
744   {
745     GNUNET_SCHEDULER_cancel (server->listen_task);
746     server->listen_task = NULL;
747   }
748   if (NULL != server->listen_sockets)
749   {
750     i = 0;
751     while (NULL != server->listen_sockets[i])
752       GNUNET_break (GNUNET_OK ==
753                     GNUNET_NETWORK_socket_close (server->listen_sockets[i++]));
754     GNUNET_free (server->listen_sockets);
755     server->listen_sockets = NULL;
756   }
757   if (GNUNET_NO == server->in_soft_shutdown)
758     server->in_soft_shutdown = GNUNET_YES;
759   test_monitor_clients (server);
760 }
761
762
763 /**
764  * Free resources held by this server.
765  *
766  * @param server server to destroy
767  */
768 void
769 GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *server)
770 {
771   struct HandlerList *hpos;
772   struct NotifyList *npos;
773   unsigned int i;
774
775   LOG (GNUNET_ERROR_TYPE_DEBUG,
776        "Server shutting down.\n");
777   if (NULL != server->listen_task)
778   {
779     GNUNET_SCHEDULER_cancel (server->listen_task);
780     server->listen_task = NULL;
781   }
782   if (NULL != server->listen_sockets)
783   {
784     i = 0;
785     while (NULL != server->listen_sockets[i])
786       GNUNET_break (GNUNET_OK ==
787                     GNUNET_NETWORK_socket_close (server->listen_sockets[i++]));
788     GNUNET_free (server->listen_sockets);
789     server->listen_sockets = NULL;
790   }
791   while (NULL != server->clients_head)
792     GNUNET_SERVER_client_disconnect (server->clients_head);
793   while (NULL != (hpos = server->handlers))
794   {
795     server->handlers = hpos->next;
796     GNUNET_free (hpos);
797   }
798   while (NULL != (npos = server->disconnect_notify_list_head))
799   {
800     npos->callback (npos->callback_cls,
801                     NULL);
802     GNUNET_CONTAINER_DLL_remove (server->disconnect_notify_list_head,
803                                  server->disconnect_notify_list_tail,
804                                  npos);
805     GNUNET_free (npos);
806   }
807   while (NULL != (npos = server->connect_notify_list_head))
808   {
809     npos->callback (npos->callback_cls,
810                     NULL);
811     GNUNET_CONTAINER_DLL_remove (server->connect_notify_list_head,
812                                  server->connect_notify_list_tail,
813                                  npos);
814     GNUNET_free (npos);
815   }
816   GNUNET_free (server);
817 }
818
819
820 /**
821  * Add additional handlers to an existing server.
822  *
823  * @param server the server to add handlers to
824  * @param handlers array of message handlers for
825  *        incoming messages; the last entry must
826  *        have "NULL" for the "callback"; multiple
827  *        entries for the same type are allowed,
828  *        they will be called in order of occurence.
829  *        These handlers can be removed later;
830  *        the handlers array must exist until removed
831  *        (or server is destroyed).
832  */
833 void
834 GNUNET_SERVER_add_handlers (struct GNUNET_SERVER_Handle *server,
835                             const struct GNUNET_SERVER_MessageHandler *handlers)
836 {
837   struct HandlerList *p;
838
839   p = GNUNET_new (struct HandlerList);
840   p->handlers = handlers;
841   p->next = server->handlers;
842   server->handlers = p;
843 }
844
845
846 /**
847  * Change functions used by the server to tokenize the message stream.
848  * (very rarely used).
849  *
850  * @param server server to modify
851  * @param create new tokenizer initialization function
852  * @param destroy new tokenizer destruction function
853  * @param receive new tokenizer receive function
854  * @param cls closure for @a create, @a receive, @a destroy
855  */
856 void
857 GNUNET_SERVER_set_callbacks (struct GNUNET_SERVER_Handle *server,
858                              GNUNET_SERVER_MstCreateCallback create,
859                              GNUNET_SERVER_MstDestroyCallback destroy,
860                              GNUNET_SERVER_MstReceiveCallback receive,
861                              void *cls)
862 {
863   server->mst_create = create;
864   server->mst_destroy = destroy;
865   server->mst_receive = receive;
866   server->mst_cls = cls;
867 }
868
869
870 /**
871  * Task run to warn about missing calls to #GNUNET_SERVER_receive_done.
872  *
873  * @param cls our `struct GNUNET_SERVER_Client *` to process more requests from
874  */
875 static void
876 warn_no_receive_done (void *cls)
877 {
878   struct GNUNET_SERVER_Client *client = cls;
879
880   GNUNET_break (0 != client->warn_type); /* type should never be 0 here, as we don't use 0 */
881   client->warn_task =
882       GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
883                                     &warn_no_receive_done, client);
884   LOG (GNUNET_ERROR_TYPE_WARNING,
885        _("Processing code for message of type %u did not call `GNUNET_SERVER_receive_done' after %s\n"),
886        (unsigned int) client->warn_type,
887        GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (client->warn_start),
888                                                GNUNET_YES));
889 }
890
891
892 /**
893  * Disable the warning the server issues if a message is not acknowledged
894  * in a timely fashion.  Use this call if a client is intentionally delayed
895  * for a while.  Only applies to the current message.
896  *
897  * @param client client for which to disable the warning
898  */
899 void
900 GNUNET_SERVER_disable_receive_done_warning (struct GNUNET_SERVER_Client *client)
901 {
902   if (NULL != client->warn_task)
903   {
904     GNUNET_SCHEDULER_cancel (client->warn_task);
905     client->warn_task = NULL;
906   }
907 }
908
909
910 /**
911  * Inject a message into the server, pretend it came
912  * from the specified client.  Delivery of the message
913  * will happen instantly (if a handler is installed;
914  * otherwise the call does nothing).
915  *
916  * @param server the server receiving the message
917  * @param sender the "pretended" sender of the message
918  *        can be NULL!
919  * @param message message to transmit
920  * @return #GNUNET_OK if the message was OK and the
921  *                   connection can stay open
922  *         #GNUNET_SYSERR if the connection to the
923  *         client should be shut down
924  */
925 int
926 GNUNET_SERVER_inject (struct GNUNET_SERVER_Handle *server,
927                       struct GNUNET_SERVER_Client *sender,
928                       const struct GNUNET_MessageHeader *message)
929 {
930   struct HandlerList *pos;
931   const struct GNUNET_SERVER_MessageHandler *mh;
932   unsigned int i;
933   uint16_t type;
934   uint16_t size;
935   int found;
936
937   type = ntohs (message->type);
938   size = ntohs (message->size);
939   LOG (GNUNET_ERROR_TYPE_INFO,
940        "Received message of type %u and size %u from client\n",
941        type, size);
942   found = GNUNET_NO;
943   for (pos = server->handlers; NULL != pos; pos = pos->next)
944   {
945     i = 0;
946     while (pos->handlers[i].callback != NULL)
947     {
948       mh = &pos->handlers[i];
949       if ((mh->type == type) || (mh->type == GNUNET_MESSAGE_TYPE_ALL))
950       {
951         if ((0 != mh->expected_size) && (mh->expected_size != size))
952         {
953 #if GNUNET8_NETWORK_IS_DEAD
954           LOG (GNUNET_ERROR_TYPE_WARNING,
955                "Expected %u bytes for message of type %u, got %u\n",
956                mh->expected_size, mh->type, size);
957           GNUNET_break_op (0);
958 #else
959           LOG (GNUNET_ERROR_TYPE_DEBUG,
960                "Expected %u bytes for message of type %u, got %u\n",
961                mh->expected_size, mh->type, size);
962 #endif
963           return GNUNET_SYSERR;
964         }
965         if (NULL != sender)
966         {
967           if ( (0 == sender->suspended) &&
968                (NULL == sender->warn_task) )
969           {
970             GNUNET_break (0 != type); /* type should never be 0 here, as we don't use 0 */
971             sender->warn_start = GNUNET_TIME_absolute_get ();
972             sender->warn_task =
973                 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
974                                               &warn_no_receive_done,
975                                               sender);
976             sender->warn_type = type;
977           }
978           sender->suspended++;
979         }
980         mh->callback (mh->callback_cls, sender, message);
981         found = GNUNET_YES;
982       }
983       i++;
984     }
985   }
986   if (GNUNET_NO == found)
987   {
988     LOG (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
989          "Received message of unknown type %d\n", type);
990     if (GNUNET_YES == server->require_found)
991       return GNUNET_SYSERR;
992   }
993   return GNUNET_OK;
994 }
995
996
997 /**
998  * We are receiving an incoming message.  Process it.
999  *
1000  * @param cls our closure (handle for the client)
1001  * @param buf buffer with data received from network
1002  * @param available number of bytes available in buf
1003  * @param addr address of the sender
1004  * @param addrlen length of @a addr
1005  * @param errCode code indicating errors receiving, 0 for success
1006  */
1007 static void
1008 process_incoming (void *cls,
1009                   const void *buf,
1010                   size_t available,
1011                   const struct sockaddr *addr,
1012                   socklen_t addrlen,
1013                   int errCode);
1014
1015
1016 /**
1017  * Process messages from the client's message tokenizer until either
1018  * the tokenizer is empty (and then schedule receiving more), or
1019  * until some handler is not immediately done (then wait for restart_processing)
1020  * or shutdown.
1021  *
1022  * @param client the client to process, RC must have already been increased
1023  *        using #GNUNET_SERVER_client_keep and will be decreased by one in this
1024  *        function
1025  * @param ret #GNUNET_NO to start processing from the buffer,
1026  *            #GNUNET_OK if the mst buffer is drained and we should instantly go back to receiving
1027  *            #GNUNET_SYSERR if we should instantly abort due to error in a previous step
1028  */
1029 static void
1030 process_mst (struct GNUNET_SERVER_Client *client,
1031              int ret)
1032 {
1033   while ((GNUNET_SYSERR != ret) && (NULL != client->server) &&
1034          (GNUNET_YES != client->shutdown_now) && (0 == client->suspended))
1035   {
1036     if (GNUNET_OK == ret)
1037     {
1038       LOG (GNUNET_ERROR_TYPE_DEBUG,
1039            "Server re-enters receive loop, timeout: %s.\n",
1040            GNUNET_STRINGS_relative_time_to_string (client->idle_timeout, GNUNET_YES));
1041       client->receive_pending = GNUNET_YES;
1042       if (GNUNET_OK !=
1043           GNUNET_CONNECTION_receive (client->connection,
1044                                      GNUNET_MAX_MESSAGE_SIZE - 1,
1045                                      client->idle_timeout,
1046                                      &process_incoming,
1047                                      client))
1048         return;
1049       break;
1050     }
1051     LOG (GNUNET_ERROR_TYPE_DEBUG,
1052          "Server processes additional messages instantly.\n");
1053     if (NULL != client->server->mst_receive)
1054       ret =
1055           client->server->mst_receive (client->server->mst_cls, client->mst,
1056                                        client, NULL, 0, GNUNET_NO, GNUNET_YES);
1057     else
1058       ret =
1059           GNUNET_SERVER_mst_receive (client->mst, client, NULL, 0, GNUNET_NO,
1060                                      GNUNET_YES);
1061   }
1062   LOG (GNUNET_ERROR_TYPE_DEBUG,
1063        "Server leaves instant processing loop: ret = %d, server = %p, shutdown = %d, suspended = %u\n",
1064        ret, client->server,
1065        client->shutdown_now,
1066        client->suspended);
1067   if (GNUNET_NO == ret)
1068   {
1069     LOG (GNUNET_ERROR_TYPE_DEBUG,
1070          "Server has more data pending but is suspended.\n");
1071     client->receive_pending = GNUNET_SYSERR;    /* data pending */
1072   }
1073   if ( (GNUNET_SYSERR == ret) ||
1074        (GNUNET_YES == client->shutdown_now) )
1075     GNUNET_SERVER_client_disconnect (client);
1076 }
1077
1078
1079 /**
1080  * We are receiving an incoming message.  Process it.
1081  *
1082  * @param cls our closure (handle for the client)
1083  * @param buf buffer with data received from network
1084  * @param available number of bytes available in buf
1085  * @param addr address of the sender
1086  * @param addrlen length of @a addr
1087  * @param errCode code indicating errors receiving, 0 for success
1088  */
1089 static void
1090 process_incoming (void *cls,
1091                   const void *buf,
1092                   size_t available,
1093                   const struct sockaddr *addr,
1094                   socklen_t addrlen,
1095                   int errCode)
1096 {
1097   struct GNUNET_SERVER_Client *client = cls;
1098   struct GNUNET_SERVER_Handle *server = client->server;
1099   struct GNUNET_TIME_Absolute end;
1100   struct GNUNET_TIME_Absolute now;
1101   int ret;
1102
1103   GNUNET_assert (GNUNET_YES == client->receive_pending);
1104   client->receive_pending = GNUNET_NO;
1105   now = GNUNET_TIME_absolute_get ();
1106   end = GNUNET_TIME_absolute_add (client->last_activity,
1107                                   client->idle_timeout);
1108
1109   if ( (NULL == buf) &&
1110        (0 == available) &&
1111        (NULL == addr) &&
1112        (0 == errCode) &&
1113        (GNUNET_YES != client->shutdown_now) &&
1114        (NULL != server) &&
1115        (GNUNET_YES == GNUNET_CONNECTION_check (client->connection)) &&
1116        (end.abs_value_us > now.abs_value_us) )
1117   {
1118     /* wait longer, timeout changed (i.e. due to us sending) */
1119     LOG (GNUNET_ERROR_TYPE_DEBUG,
1120          "Receive time out, but no disconnect due to sending (%p)\n",
1121          client);
1122     client->receive_pending = GNUNET_YES;
1123     GNUNET_CONNECTION_receive (client->connection,
1124                                GNUNET_MAX_MESSAGE_SIZE - 1,
1125                                GNUNET_TIME_absolute_get_remaining (end),
1126                                &process_incoming,
1127                                client);
1128     return;
1129   }
1130   if ( (NULL == buf) ||
1131        (0 == available) ||
1132        (0 != errCode) ||
1133        (NULL == server) ||
1134        (GNUNET_YES == client->shutdown_now) ||
1135        (GNUNET_YES != GNUNET_CONNECTION_check (client->connection)) )
1136   {
1137     /* other side closed connection, error connecting, etc. */
1138     LOG (GNUNET_ERROR_TYPE_DEBUG,
1139          "Failed to connect or other side closed connection (%p)\n",
1140          client);
1141     GNUNET_SERVER_client_disconnect (client);
1142     return;
1143   }
1144   LOG (GNUNET_ERROR_TYPE_DEBUG,
1145        "Server receives %u bytes from `%s'.\n",
1146        (unsigned int) available,
1147        GNUNET_a2s (addr, addrlen));
1148   GNUNET_SERVER_client_keep (client);
1149   client->last_activity = now;
1150
1151   if (NULL != server->mst_receive)
1152   {
1153     ret = client->server->mst_receive (client->server->mst_cls,
1154                                        client->mst,
1155                                        client,
1156                                        buf,
1157                                        available,
1158                                        GNUNET_NO,
1159                                        GNUNET_YES);
1160   }
1161   else if (NULL != client->mst)
1162   {
1163     ret =
1164         GNUNET_SERVER_mst_receive (client->mst,
1165                                    client,
1166                                    buf,
1167                                    available,
1168                                    GNUNET_NO,
1169                                    GNUNET_YES);
1170   }
1171   else
1172   {
1173     GNUNET_break (0);
1174     return;
1175   }
1176   process_mst (client,
1177                ret);
1178   GNUNET_SERVER_client_drop (client);
1179 }
1180
1181
1182 /**
1183  * Task run to start again receiving from the network
1184  * and process requests.
1185  *
1186  * @param cls our `struct GNUNET_SERVER_Client *` to process more requests from
1187  */
1188 static void
1189 restart_processing (void *cls)
1190 {
1191   struct GNUNET_SERVER_Client *client = cls;
1192
1193   GNUNET_assert (GNUNET_YES != client->shutdown_now);
1194   client->restart_task = NULL;
1195   if (GNUNET_NO == client->receive_pending)
1196   {
1197     LOG (GNUNET_ERROR_TYPE_DEBUG, "Server begins to read again from client.\n");
1198     client->receive_pending = GNUNET_YES;
1199     GNUNET_CONNECTION_receive (client->connection,
1200                                GNUNET_MAX_MESSAGE_SIZE - 1,
1201                                client->idle_timeout,
1202                                &process_incoming,
1203                                client);
1204     return;
1205   }
1206   LOG (GNUNET_ERROR_TYPE_DEBUG,
1207        "Server continues processing messages still in the buffer.\n");
1208   GNUNET_SERVER_client_keep (client);
1209   client->receive_pending = GNUNET_NO;
1210   process_mst (client,
1211                GNUNET_NO);
1212   GNUNET_SERVER_client_drop (client);
1213 }
1214
1215
1216 /**
1217  * This function is called whenever our inbound message tokenizer has
1218  * received a complete message.
1219  *
1220  * @param cls closure (struct GNUNET_SERVER_Handle)
1221  * @param client identification of the client (`struct GNUNET_SERVER_Client *`)
1222  * @param message the actual message
1223  *
1224  * @return #GNUNET_OK on success, #GNUNET_SYSERR to stop further processing
1225  */
1226 static int
1227 client_message_tokenizer_callback (void *cls,
1228                                    void *client,
1229                                    const struct GNUNET_MessageHeader *message)
1230 {
1231   struct GNUNET_SERVER_Handle *server = cls;
1232   struct GNUNET_SERVER_Client *sender = client;
1233   int ret;
1234
1235   LOG (GNUNET_ERROR_TYPE_DEBUG,
1236        "Tokenizer gives server message of type %u and size %u from client\n",
1237        ntohs (message->type), ntohs (message->size));
1238   sender->in_process_client_buffer = GNUNET_YES;
1239   ret = GNUNET_SERVER_inject (server, sender, message);
1240   sender->in_process_client_buffer = GNUNET_NO;
1241   if ( (GNUNET_OK != ret) || (GNUNET_YES == sender->shutdown_now) )
1242   {
1243     GNUNET_SERVER_client_disconnect (sender);
1244     return GNUNET_SYSERR;
1245   }
1246   return GNUNET_OK;
1247 }
1248
1249
1250 /**
1251  * Add a TCP socket-based connection to the set of handles managed by
1252  * this server.  Use this function for outgoing (P2P) connections that
1253  * we initiated (and where this server should process incoming
1254  * messages).
1255  *
1256  * @param server the server to use
1257  * @param connection the connection to manage (client must
1258  *        stop using this connection from now on)
1259  * @return the client handle
1260  */
1261 struct GNUNET_SERVER_Client *
1262 GNUNET_SERVER_connect_socket (struct GNUNET_SERVER_Handle *server,
1263                               struct GNUNET_CONNECTION_Handle *connection)
1264 {
1265   struct GNUNET_SERVER_Client *client;
1266   struct NotifyList *n;
1267
1268   client = GNUNET_new (struct GNUNET_SERVER_Client);
1269   client->connection = connection;
1270   client->server = server;
1271   client->last_activity = GNUNET_TIME_absolute_get ();
1272   client->idle_timeout = server->idle_timeout;
1273   GNUNET_CONTAINER_DLL_insert (server->clients_head,
1274                                server->clients_tail,
1275                                client);
1276   if (NULL != server->mst_create)
1277     client->mst =
1278         server->mst_create (server->mst_cls, client);
1279   else
1280     client->mst =
1281         GNUNET_SERVER_mst_create (&client_message_tokenizer_callback,
1282                                   server);
1283   GNUNET_assert (NULL != client->mst);
1284   for (n = server->connect_notify_list_head; NULL != n; n = n->next)
1285     n->callback (n->callback_cls, client);
1286   client->receive_pending = GNUNET_YES;
1287   if (GNUNET_SYSERR ==
1288       GNUNET_CONNECTION_receive (client->connection,
1289                                  GNUNET_MAX_MESSAGE_SIZE - 1,
1290                                  client->idle_timeout,
1291                                  &process_incoming,
1292                                  client))
1293     return NULL;
1294   return client;
1295 }
1296
1297
1298 /**
1299  * Change the timeout for a particular client.  Decreasing the timeout
1300  * may not go into effect immediately (only after the previous timeout
1301  * times out or activity happens on the socket).
1302  *
1303  * @param client the client to update
1304  * @param timeout new timeout for activities on the socket
1305  */
1306 void
1307 GNUNET_SERVER_client_set_timeout (struct GNUNET_SERVER_Client *client,
1308                                   struct GNUNET_TIME_Relative timeout)
1309 {
1310   client->idle_timeout = timeout;
1311 }
1312
1313
1314 /**
1315  * Notify the server that the given client handle should
1316  * be kept (keeps the connection up if possible, increments
1317  * the internal reference counter).
1318  *
1319  * @param client the client to keep
1320  */
1321 void
1322 GNUNET_SERVER_client_keep (struct GNUNET_SERVER_Client *client)
1323 {
1324   client->reference_count++;
1325 }
1326
1327
1328 /**
1329  * Notify the server that the given client handle is no
1330  * longer required.  Decrements the reference counter.  If
1331  * that counter reaches zero an inactive connection maybe
1332  * closed.
1333  *
1334  * @param client the client to drop
1335  */
1336 void
1337 GNUNET_SERVER_client_drop (struct GNUNET_SERVER_Client *client)
1338 {
1339   GNUNET_assert (client->reference_count > 0);
1340   client->reference_count--;
1341   if ((GNUNET_YES == client->shutdown_now) && (0 == client->reference_count))
1342     GNUNET_SERVER_client_disconnect (client);
1343 }
1344
1345
1346 /**
1347  * Obtain the network address of the other party.
1348  *
1349  * @param client the client to get the address for
1350  * @param addr where to store the address
1351  * @param addrlen where to store the length of the @a addr
1352  * @return #GNUNET_OK on success
1353  */
1354 int
1355 GNUNET_SERVER_client_get_address (struct GNUNET_SERVER_Client *client,
1356                                   void **addr, size_t * addrlen)
1357 {
1358   return GNUNET_CONNECTION_get_address (client->connection, addr, addrlen);
1359 }
1360
1361
1362 /**
1363  * Ask the server to notify us whenever a client disconnects.
1364  * This function is called whenever the actual network connection
1365  * is closed; the reference count may be zero or larger than zero
1366  * at this point.
1367  *
1368  * @param server the server manageing the clients
1369  * @param callback function to call on disconnect
1370  * @param callback_cls closure for @a callback
1371  */
1372 void
1373 GNUNET_SERVER_disconnect_notify (struct GNUNET_SERVER_Handle *server,
1374                                  GNUNET_SERVER_DisconnectCallback callback,
1375                                  void *callback_cls)
1376 {
1377   struct NotifyList *n;
1378
1379   n = GNUNET_new (struct NotifyList);
1380   n->callback = callback;
1381   n->callback_cls = callback_cls;
1382   GNUNET_CONTAINER_DLL_insert (server->disconnect_notify_list_head,
1383                                server->disconnect_notify_list_tail,
1384                                n);
1385 }
1386
1387
1388 /**
1389  * Ask the server to notify us whenever a client connects.
1390  * This function is called whenever the actual network connection
1391  * is opened. If the server is destroyed before this
1392  * notification is explicitly cancelled, the 'callback' will
1393  * once be called with a 'client' argument of NULL to indicate
1394  * that the server itself is now gone (and that the callback
1395  * won't be called anymore and also can no longer be cancelled).
1396  *
1397  * @param server the server manageing the clients
1398  * @param callback function to call on sconnect
1399  * @param callback_cls closure for @a callback
1400  */
1401 void
1402 GNUNET_SERVER_connect_notify (struct GNUNET_SERVER_Handle *server,
1403                               GNUNET_SERVER_ConnectCallback callback,
1404                               void *callback_cls)
1405 {
1406   struct NotifyList *n;
1407   struct GNUNET_SERVER_Client *client;
1408
1409   n = GNUNET_new (struct NotifyList);
1410   n->callback = callback;
1411   n->callback_cls = callback_cls;
1412   GNUNET_CONTAINER_DLL_insert (server->connect_notify_list_head,
1413                                server->connect_notify_list_tail,
1414                                n);
1415   for (client = server->clients_head; NULL != client; client = client->next)
1416     callback (callback_cls, client);
1417 }
1418
1419
1420 /**
1421  * Ask the server to stop notifying us whenever a client connects.
1422  *
1423  * @param server the server manageing the clients
1424  * @param callback function to call on connect
1425  * @param callback_cls closure for @a callback
1426  */
1427 void
1428 GNUNET_SERVER_disconnect_notify_cancel (struct GNUNET_SERVER_Handle *server,
1429                                         GNUNET_SERVER_DisconnectCallback callback,
1430                                         void *callback_cls)
1431 {
1432   struct NotifyList *pos;
1433
1434   for (pos = server->disconnect_notify_list_head; NULL != pos; pos = pos->next)
1435     if ((pos->callback == callback) && (pos->callback_cls == callback_cls))
1436       break;
1437   if (NULL == pos)
1438   {
1439     GNUNET_break (0);
1440     return;
1441   }
1442   GNUNET_CONTAINER_DLL_remove (server->disconnect_notify_list_head,
1443                                server->disconnect_notify_list_tail,
1444                                pos);
1445   GNUNET_free (pos);
1446 }
1447
1448
1449 /**
1450  * Ask the server to stop notifying us whenever a client disconnects.
1451  *
1452  * @param server the server manageing the clients
1453  * @param callback function to call on disconnect
1454  * @param callback_cls closure for @a callback
1455  */
1456 void
1457 GNUNET_SERVER_connect_notify_cancel (struct GNUNET_SERVER_Handle *server,
1458                                      GNUNET_SERVER_ConnectCallback callback,
1459                                      void *callback_cls)
1460 {
1461   struct NotifyList *pos;
1462
1463   for (pos = server->connect_notify_list_head; NULL != pos; pos = pos->next)
1464     if ((pos->callback == callback) && (pos->callback_cls == callback_cls))
1465       break;
1466   if (NULL == pos)
1467   {
1468     GNUNET_break (0);
1469     return;
1470   }
1471   GNUNET_CONTAINER_DLL_remove (server->connect_notify_list_head,
1472                                server->connect_notify_list_tail,
1473                                pos);
1474   GNUNET_free (pos);
1475 }
1476
1477
1478 /**
1479  * Ask the server to disconnect from the given client.
1480  * This is the same as returning #GNUNET_SYSERR from a message
1481  * handler, except that it allows dropping of a client even
1482  * when not handling a message from that client.
1483  *
1484  * @param client the client to disconnect from
1485  */
1486 void
1487 GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client)
1488 {
1489   struct GNUNET_SERVER_Handle *server = client->server;
1490   struct NotifyList *n;
1491
1492   LOG (GNUNET_ERROR_TYPE_DEBUG,
1493        "Client is being disconnected from the server.\n");
1494   if (NULL != client->restart_task)
1495   {
1496     GNUNET_SCHEDULER_cancel (client->restart_task);
1497     client->restart_task = NULL;
1498   }
1499   if (NULL != client->warn_task)
1500   {
1501     GNUNET_SCHEDULER_cancel (client->warn_task);
1502     client->warn_task = NULL;
1503   }
1504   if (GNUNET_YES == client->receive_pending)
1505   {
1506     GNUNET_CONNECTION_receive_cancel (client->connection);
1507     client->receive_pending = GNUNET_NO;
1508   }
1509   client->shutdown_now = GNUNET_YES;
1510   client->reference_count++; /* make sure nobody else clean up client... */
1511   if ( (NULL != client->mst) &&
1512        (NULL != server) )
1513   {
1514     GNUNET_CONTAINER_DLL_remove (server->clients_head,
1515                                  server->clients_tail,
1516                                  client);
1517     if (NULL != server->mst_destroy)
1518       server->mst_destroy (server->mst_cls,
1519                            client->mst);
1520     else
1521       GNUNET_SERVER_mst_destroy (client->mst);
1522     client->mst = NULL;
1523     for (n = server->disconnect_notify_list_head; NULL != n; n = n->next)
1524       n->callback (n->callback_cls,
1525                    client);
1526   }
1527   client->reference_count--;
1528   if (client->reference_count > 0)
1529   {
1530     LOG (GNUNET_ERROR_TYPE_DEBUG,
1531          "RC of %p still positive, not destroying everything.\n",
1532          client);
1533     client->server = NULL;
1534     return;
1535   }
1536   if (GNUNET_YES == client->in_process_client_buffer)
1537   {
1538     LOG (GNUNET_ERROR_TYPE_DEBUG,
1539          "Still processing inputs of %p, not destroying everything.\n",
1540          client);
1541     return;
1542   }
1543   LOG (GNUNET_ERROR_TYPE_DEBUG,
1544        "RC of %p now zero, destroying everything.\n",
1545        client);
1546   if (GNUNET_YES == client->persist)
1547     GNUNET_CONNECTION_persist_ (client->connection);
1548   if (NULL != client->th.cth)
1549     GNUNET_SERVER_notify_transmit_ready_cancel (&client->th);
1550   GNUNET_CONNECTION_destroy (client->connection);
1551   /* need to cancel again, as it might have been re-added
1552      in the meantime (i.e. during callbacks) */
1553   if (NULL != client->warn_task)
1554   {
1555     GNUNET_SCHEDULER_cancel (client->warn_task);
1556     client->warn_task = NULL;
1557   }
1558   if (GNUNET_YES == client->receive_pending)
1559   {
1560     GNUNET_CONNECTION_receive_cancel (client->connection);
1561     client->receive_pending = GNUNET_NO;
1562   }
1563   GNUNET_free (client);
1564   /* we might be in soft-shutdown, test if we're done */
1565   if (NULL != server)
1566     test_monitor_clients (server);
1567 }
1568
1569
1570 /**
1571  * Disable the "CORK" feature for communication with the given client,
1572  * forcing the OS to immediately flush the buffer on transmission
1573  * instead of potentially buffering multiple messages.
1574  *
1575  * @param client handle to the client
1576  * @return #GNUNET_OK on success
1577  */
1578 int
1579 GNUNET_SERVER_client_disable_corking (struct GNUNET_SERVER_Client *client)
1580 {
1581   return GNUNET_CONNECTION_disable_corking (client->connection);
1582 }
1583
1584
1585 /**
1586  * Wrapper for transmission notification that calls the original
1587  * callback and update the last activity time for our connection.
1588  *
1589  * @param cls the `struct GNUNET_SERVER_Client *`
1590  * @param size number of bytes we can transmit
1591  * @param buf where to copy the message
1592  * @return number of bytes actually transmitted
1593  */
1594 static size_t
1595 transmit_ready_callback_wrapper (void *cls, size_t size, void *buf)
1596 {
1597   struct GNUNET_SERVER_Client *client = cls;
1598   GNUNET_CONNECTION_TransmitReadyNotify callback;
1599
1600   client->th.cth = NULL;
1601   callback = client->th.callback;
1602   client->th.callback = NULL;
1603   client->last_activity = GNUNET_TIME_absolute_get ();
1604   return callback (client->th.callback_cls, size, buf);
1605 }
1606
1607
1608 /**
1609  * Notify us when the server has enough space to transmit
1610  * a message of the given size to the given client.
1611  *
1612  * @param client client to transmit message to
1613  * @param size requested amount of buffer space
1614  * @param timeout after how long should we give up (and call
1615  *        notify with buf NULL and size 0)?
1616  * @param callback function to call when space is available
1617  * @param callback_cls closure for @a callback
1618  * @return non-NULL if the notify callback was queued; can be used
1619  *         to cancel the request using
1620  *         #GNUNET_SERVER_notify_transmit_ready_cancel().
1621  *         NULL if we are already going to notify someone else (busy)
1622  */
1623 struct GNUNET_SERVER_TransmitHandle *
1624 GNUNET_SERVER_notify_transmit_ready (struct GNUNET_SERVER_Client *client,
1625                                      size_t size,
1626                                      struct GNUNET_TIME_Relative timeout,
1627                                      GNUNET_CONNECTION_TransmitReadyNotify callback,
1628                                      void *callback_cls)
1629 {
1630   if (NULL != client->th.callback)
1631     return NULL;
1632   client->th.callback_cls = callback_cls;
1633   client->th.callback = callback;
1634   client->th.cth = GNUNET_CONNECTION_notify_transmit_ready (client->connection, size,
1635                                                             timeout,
1636                                                             &transmit_ready_callback_wrapper,
1637                                                             client);
1638   return &client->th;
1639 }
1640
1641
1642 /**
1643  * Abort transmission request.
1644  *
1645  * @param th request to abort
1646  */
1647 void
1648 GNUNET_SERVER_notify_transmit_ready_cancel (struct GNUNET_SERVER_TransmitHandle *th)
1649 {
1650   GNUNET_CONNECTION_notify_transmit_ready_cancel (th->cth);
1651   th->cth = NULL;
1652   th->callback = NULL;
1653 }
1654
1655
1656 /**
1657  * Set the persistent flag on this client, used to setup client connection
1658  * to only be killed when the service it's connected to is actually dead.
1659  *
1660  * @param client the client to set the persistent flag on
1661  */
1662 void
1663 GNUNET_SERVER_client_persist_ (struct GNUNET_SERVER_Client *client)
1664 {
1665   client->persist = GNUNET_YES;
1666 }
1667
1668
1669 /**
1670  * Resume receiving from this client, we are done processing the
1671  * current request.  This function must be called from within each
1672  * GNUNET_SERVER_MessageCallback (or its respective continuations).
1673  *
1674  * @param client client we were processing a message of
1675  * @param success #GNUNET_OK to keep the connection open and
1676  *                          continue to receive
1677  *                #GNUNET_NO to close the connection (normal behavior)
1678  *                #GNUNET_SYSERR to close the connection (signal
1679  *                          serious error)
1680  */
1681 void
1682 GNUNET_SERVER_receive_done (struct GNUNET_SERVER_Client *client,
1683                             int success)
1684 {
1685   if (NULL == client)
1686     return;
1687   GNUNET_assert (client->suspended > 0);
1688   client->suspended--;
1689   if (GNUNET_OK != success)
1690   {
1691     LOG (GNUNET_ERROR_TYPE_DEBUG,
1692          "GNUNET_SERVER_receive_done called with failure indication\n");
1693     if ( (client->reference_count > 0) || (client->suspended > 0) )
1694       client->shutdown_now = GNUNET_YES;
1695     else
1696       GNUNET_SERVER_client_disconnect (client);
1697     return;
1698   }
1699   if (client->suspended > 0)
1700   {
1701     LOG (GNUNET_ERROR_TYPE_DEBUG,
1702          "GNUNET_SERVER_receive_done called, but more clients pending\n");
1703     return;
1704   }
1705   if (NULL != client->warn_task)
1706   {
1707     GNUNET_SCHEDULER_cancel (client->warn_task);
1708     client->warn_task = NULL;
1709   }
1710   if (GNUNET_YES == client->in_process_client_buffer)
1711   {
1712     LOG (GNUNET_ERROR_TYPE_DEBUG,
1713          "GNUNET_SERVER_receive_done called while still in processing loop\n");
1714     return;
1715   }
1716   if ((NULL == client->server) || (GNUNET_YES == client->shutdown_now))
1717   {
1718     GNUNET_SERVER_client_disconnect (client);
1719     return;
1720   }
1721   LOG (GNUNET_ERROR_TYPE_DEBUG,
1722        "GNUNET_SERVER_receive_done causes restart in reading from the socket\n");
1723   GNUNET_assert (NULL == client->restart_task);
1724   client->restart_task = GNUNET_SCHEDULER_add_now (&restart_processing,
1725                                                    client);
1726 }
1727
1728
1729 /* end of server.c */