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