Don't shadow the system() function
[oweals/gnunet.git] / src / util / server.c
index e25ada3041f6cff85670b92146da008e4c7d2234..1a4b73126397f1c9d8c6076824fc014b1dce857c 100644 (file)
@@ -1,10 +1,10 @@
 /*
      This file is part of GNUnet.
 /*
      This file is part of GNUnet.
-     (C) 2009, 2012 Christian Grothoff (and other contributing authors)
+     Copyright (C) 2009-2013 Christian Grothoff (and other contributing authors)
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 2, or (at your
+     by the Free Software Foundation; either version 3, or (at your
      option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
      option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
@@ -25,7 +25,6 @@
  */
 
 #include "platform.h"
  */
 
 #include "platform.h"
-#include "gnunet_common.h"
 #include "gnunet_util_lib.h"
 #include "gnunet_protocols.h"
 
 #include "gnunet_util_lib.h"
 #include "gnunet_protocols.h"
 
@@ -110,15 +109,25 @@ struct GNUNET_SERVER_Handle
    */
   struct NotifyList *disconnect_notify_list_tail;
 
    */
   struct NotifyList *disconnect_notify_list_tail;
 
+  /**
+   * Head of linked list of functions to call on connects by clients.
+   */
+  struct NotifyList *connect_notify_list_head;
+
+  /**
+   * Tail of linked list of functions to call on connects by clients.
+   */
+  struct NotifyList *connect_notify_list_tail;
+
   /**
    * Function to call for access control.
    */
   /**
    * Function to call for access control.
    */
-  GNUNET_CONNECTION_AccessCheck access;
+  GNUNET_CONNECTION_AccessCheck access_cb;
 
   /**
 
   /**
-   * Closure for access.
+   * Closure for @e access_cb.
    */
    */
-  void *access_cls;
+  void *access_cb_cls;
 
   /**
    * NULL-terminated array of sockets used to listen for new
 
   /**
    * NULL-terminated array of sockets used to listen for new
@@ -135,7 +144,7 @@ struct GNUNET_SERVER_Handle
   /**
    * Task scheduled to do the listening.
    */
   /**
    * Task scheduled to do the listening.
    */
-  GNUNET_SCHEDULER_TaskIdentifier listen_task;
+  struct GNUNET_SCHEDULER_Task * listen_task;
 
   /**
    * Alternative function to create a MST instance.
 
   /**
    * Alternative function to create a MST instance.
@@ -164,10 +173,10 @@ struct GNUNET_SERVER_Handle
   int require_found;
 
   /**
   int require_found;
 
   /**
-   * Set to GNUNET_YES once we are in 'soft' shutdown where we wait for
+   * Set to #GNUNET_YES once we are in 'soft' shutdown where we wait for
    * all non-monitor clients to disconnect before we call
    * all non-monitor clients to disconnect before we call
-   * GNUNET_SERVER_destroy.  See 'test_monitor_clients'.  Set to
-   * GNUNET_SYSERR once the final destroy task has been scheduled
+   * #GNUNET_SERVER_destroy.  See test_monitor_clients().  Set to
+   * #GNUNET_SYSERR once the final destroy task has been scheduled
    * (we cannot run it in the same task).
    */
   int in_soft_shutdown;
    * (we cannot run it in the same task).
    */
   int in_soft_shutdown;
@@ -185,7 +194,7 @@ struct GNUNET_SERVER_TransmitHandle
   GNUNET_CONNECTION_TransmitReadyNotify callback;
 
   /**
   GNUNET_CONNECTION_TransmitReadyNotify callback;
 
   /**
-   * Closure for 'callback'
+   * Closure for @e callback
    */
   void *callback_cls;
 
    */
   void *callback_cls;
 
@@ -228,15 +237,21 @@ struct GNUNET_SERVER_Client
    */
   struct GNUNET_CONNECTION_Handle *connection;
 
    */
   struct GNUNET_CONNECTION_Handle *connection;
 
+  /**
+   * User context value, manipulated using
+   * 'GNUNET_SERVER_client_{get/set}_user_context' functions.
+   */
+  void *user_context;
+
   /**
    * ID of task used to restart processing.
    */
   /**
    * ID of task used to restart processing.
    */
-  GNUNET_SCHEDULER_TaskIdentifier restart_task;
+  struct GNUNET_SCHEDULER_Task * restart_task;
 
   /**
 
   /**
-   * Task that warns about missing calls to 'GNUNET_SERVER_receive_done'.
+   * Task that warns about missing calls to #GNUNET_SERVER_receive_done.
    */
    */
-  GNUNET_SCHEDULER_TaskIdentifier warn_task;
+  struct GNUNET_SCHEDULER_Task * warn_task;
 
   /**
    * Time when the warn task was started.
 
   /**
    * Time when the warn task was started.
@@ -251,7 +266,7 @@ struct GNUNET_SERVER_Client
 
   /**
    * Transmission handle we return for this client from
 
   /**
    * Transmission handle we return for this client from
-   * GNUNET_SERVER_notify_transmit_ready.
+   * #GNUNET_SERVER_notify_transmit_ready.
    */
   struct GNUNET_SERVER_TransmitHandle th;
 
    */
   struct GNUNET_SERVER_TransmitHandle th;
 
@@ -275,6 +290,12 @@ struct GNUNET_SERVER_Client
    */
   unsigned int suspended;
 
    */
   unsigned int suspended;
 
+  /**
+   * Last size given when user context was initialized; used for
+   * sanity check.
+   */
+  size_t user_context_size;
+
   /**
    * Are we currently in the "process_client_buffer" function (and
    * will hence restart the receive job on exit if suspended == 0 once
   /**
    * Are we currently in the "process_client_buffer" function (and
    * will hence restart the receive job on exit if suspended == 0 once
@@ -291,16 +312,12 @@ struct GNUNET_SERVER_Client
   int shutdown_now;
 
   /**
   int shutdown_now;
 
   /**
-   * Are we currently trying to receive? (YES if we are, NO if we are not,
-   * SYSERR if data is already available in MST).
+   * Are we currently trying to receive? (#GNUNET_YES if we are,
+   * #GNUNET_NO if we are not, #GNUNET_SYSERR if data is already
+   * available in MST).
    */
   int receive_pending;
 
    */
   int receive_pending;
 
-  /**
-   * Finish pending write when disconnecting?
-   */
-  int finish_pending_write;
-
   /**
    * Persist the file handle for this client no matter what happens,
    * force the OS to close once the process actually dies.  Should only
   /**
    * Persist the file handle for this client no matter what happens,
    * force the OS to close once the process actually dies.  Should only
@@ -311,7 +328,7 @@ struct GNUNET_SERVER_Client
   /**
    * Is this client a 'monitor' client that should not be counted
    * when deciding on destroying the server during soft shutdown?
   /**
    * Is this client a 'monitor' client that should not be counted
    * when deciding on destroying the server during soft shutdown?
-   * (see also GNUNET_SERVICE_start)
+   * (see also #GNUNET_SERVICE_start)
    */
   int is_monitor;
 
    */
   int is_monitor;
 
@@ -322,51 +339,48 @@ struct GNUNET_SERVER_Client
 };
 
 
 };
 
 
+
 /**
 /**
- * Scheduler says our listen socket is ready.  Process it!
+ * Return user context associated with the given client.
+ * Note: you should probably use the macro (call without the underscore).
  *
  *
- * @param cls handle to our server for which we are processing the listen
- *        socket
- * @param tc reason why we are running right now
+ * @param client client to query
+ * @param size number of bytes in user context struct (for verification only)
+ * @return pointer to user context
  */
  */
-static void
-process_listen_socket (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
+void *
+GNUNET_SERVER_client_get_user_context_ (struct GNUNET_SERVER_Client *client,
+                                       size_t size)
+{
+  if ((0 == client->user_context_size) &&
+      (NULL == client->user_context))
+    return NULL; /* never set */
+  GNUNET_assert (size == client->user_context_size);
+  return client->user_context;
+}
 
 
 /**
 
 
 /**
- * Add a listen task with the scheduler for this server.
+ * Set user context to be associated with the given client.
+ * Note: you should probably use the macro (call without the underscore).
  *
  *
- * @param server handle to our server for which we are adding the listen
- *        socket
+ * @param client client to query
+ * @param ptr pointer to user context
+ * @param size number of bytes in user context struct (for verification only)
  */
  */
-static void
-schedule_listen_task (struct GNUNET_SERVER_Handle *server)
+void
+GNUNET_SERVER_client_set_user_context_ (struct GNUNET_SERVER_Client *client,
+                                       void *ptr,
+                                       size_t size)
 {
 {
-  struct GNUNET_NETWORK_FDSet *r;
-  unsigned int i;
-
-  if (NULL == server->listen_sockets[0])
-    return; /* nothing to do, no listen sockets! */
-  if (NULL == server->listen_sockets[1])
+  if (NULL == ptr)
   {
   {
-    /* simplified method: no fd set needed; this is then much simpler and
-       much more efficient */
-    server->listen_task =
-      GNUNET_SCHEDULER_add_read_net_with_priority (GNUNET_TIME_UNIT_FOREVER_REL,
-                                                  GNUNET_SCHEDULER_PRIORITY_HIGH,
-                                                  server->listen_sockets[0],
-                                                  &process_listen_socket, server);
+    client->user_context_size = 0;
+    client->user_context = ptr;
     return;
   }
     return;
   }
-  r = GNUNET_NETWORK_fdset_create ();
-  i = 0;
-  while (NULL != server->listen_sockets[i])
-    GNUNET_NETWORK_fdset_set (r, server->listen_sockets[i++]);
-  server->listen_task =
-    GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH,
-                                GNUNET_TIME_UNIT_FOREVER_REL, r, NULL,
-                                &process_listen_socket, server);
-  GNUNET_NETWORK_fdset_destroy (r);
+  client->user_context_size = size;
+  client->user_context = ptr;
 }
 
 
 }
 
 
@@ -378,66 +392,64 @@ schedule_listen_task (struct GNUNET_SERVER_Handle *server)
  * @param tc reason why we are running right now
  */
 static void
  * @param tc reason why we are running right now
  */
 static void
-process_listen_socket (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+process_listen_socket (void *cls,
+                       const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
   struct GNUNET_SERVER_Handle *server = cls;
   struct GNUNET_CONNECTION_Handle *sock;
 {
   struct GNUNET_SERVER_Handle *server = cls;
   struct GNUNET_CONNECTION_Handle *sock;
-  struct GNUNET_SERVER_Client *client;
   unsigned int i;
 
   unsigned int i;
 
-  server->listen_task = GNUNET_SCHEDULER_NO_TASK;
+  server->listen_task = NULL;
   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
   {
     /* ignore shutdown, someone else will take care of it! */
   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
   {
     /* ignore shutdown, someone else will take care of it! */
-    schedule_listen_task (server);
+    GNUNET_SERVER_resume (server);
     return;
   }
     return;
   }
-  i = 0;
-  while (NULL != server->listen_sockets[i])
+  for (i = 0; NULL != server->listen_sockets[i]; i++)
   {
   {
-    if (GNUNET_NETWORK_fdset_isset (tc->read_ready, server->listen_sockets[i]))
+    if (GNUNET_NETWORK_fdset_isset (tc->read_ready,
+                                    server->listen_sockets[i]))
     {
       sock =
     {
       sock =
-          GNUNET_CONNECTION_create_from_accept (server->access,
-                                                server->access_cls,
+          GNUNET_CONNECTION_create_from_accept (server->access_cb,
+                                                server->access_cb_cls,
                                                 server->listen_sockets[i]);
       if (NULL != sock)
       {
                                                 server->listen_sockets[i]);
       if (NULL != sock)
       {
-        LOG (GNUNET_ERROR_TYPE_DEBUG, "Server accepted incoming connection.\n");
-        client = GNUNET_SERVER_connect_socket (server, sock);
-        /* decrement reference count, we don't keep "client" alive */
-        GNUNET_SERVER_client_drop (client);
+        LOG (GNUNET_ERROR_TYPE_DEBUG,
+             "Server accepted incoming connection.\n");
+        (void) GNUNET_SERVER_connect_socket (server,
+                                             sock);
       }
     }
       }
     }
-    i++;
   }
   /* listen for more! */
   }
   /* listen for more! */
-  schedule_listen_task (server);
+  GNUNET_SERVER_resume (server);
 }
 
 
 /**
  * Create and initialize a listen socket for the server.
  *
 }
 
 
 /**
  * Create and initialize a listen socket for the server.
  *
- * @param serverAddr address to listen on
- * @param socklen length of address
+ * @param server_addr address to listen on
+ * @param socklen length of @a server_addr
  * @return NULL on error, otherwise the listen socket
  */
 static struct GNUNET_NETWORK_Handle *
  * @return NULL on error, otherwise the listen socket
  */
 static struct GNUNET_NETWORK_Handle *
-open_listen_socket (const struct sockaddr *serverAddr, socklen_t socklen)
+open_listen_socket (const struct sockaddr *server_addr, socklen_t socklen)
 {
 {
-  static int on = 1;
   struct GNUNET_NETWORK_Handle *sock;
   uint16_t port;
   int eno;
 
   struct GNUNET_NETWORK_Handle *sock;
   uint16_t port;
   int eno;
 
-  switch (serverAddr->sa_family)
+  switch (server_addr->sa_family)
   {
   case AF_INET:
   {
   case AF_INET:
-    port = ntohs (((const struct sockaddr_in *) serverAddr)->sin_port);
+    port = ntohs (((const struct sockaddr_in *) server_addr)->sin_port);
     break;
   case AF_INET6:
     break;
   case AF_INET6:
-    port = ntohs (((const struct sockaddr_in6 *) serverAddr)->sin6_port);
+    port = ntohs (((const struct sockaddr_in6 *) server_addr)->sin6_port);
     break;
   case AF_UNIX:
     port = 0;
     break;
   case AF_UNIX:
     port = 0;
@@ -447,29 +459,15 @@ open_listen_socket (const struct sockaddr *serverAddr, socklen_t socklen)
     port = 0;
     break;
   }
     port = 0;
     break;
   }
-  sock = GNUNET_NETWORK_socket_create (serverAddr->sa_family, SOCK_STREAM, 0);
+  sock = GNUNET_NETWORK_socket_create (server_addr->sa_family, SOCK_STREAM, 0);
   if (NULL == sock)
   {
     LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket");
     errno = 0;
     return NULL;
   }
   if (NULL == sock)
   {
     LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket");
     errno = 0;
     return NULL;
   }
-  if (0 != port)
-  {
-    if (GNUNET_NETWORK_socket_setsockopt
-        (sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) != GNUNET_OK)
-      LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
-                    "setsockopt");
-#ifdef IPV6_V6ONLY
-    if ((AF_INET6 == serverAddr->sa_family) &&
-        (GNUNET_NETWORK_socket_setsockopt
-         (sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on)) != GNUNET_OK))
-      LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
-                    "setsockopt");
-#endif
-  }
   /* bind the socket */
   /* bind the socket */
-  if (GNUNET_OK != GNUNET_NETWORK_socket_bind (sock, serverAddr, socklen))
+  if (GNUNET_OK != GNUNET_NETWORK_socket_bind (sock, server_addr, socklen))
   {
     eno = errno;
     if (EADDRINUSE != errno)
   {
     eno = errno;
     if (EADDRINUSE != errno)
@@ -478,11 +476,14 @@ open_listen_socket (const struct sockaddr *serverAddr, socklen_t socklen)
        * fail if we already took the port on IPv6; if both IPv4 and
        * IPv6 binds fail, then our caller will log using the
        * errno preserved in 'eno' */
        * fail if we already took the port on IPv6; if both IPv4 and
        * IPv6 binds fail, then our caller will log using the
        * errno preserved in 'eno' */
-      LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "bind");
+      LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
+                    "bind");
       if (0 != port)
       if (0 != port)
-        LOG (GNUNET_ERROR_TYPE_ERROR, _("`%s' failed for port %d (%s).\n"),
-             "bind", port,
-             (AF_INET == serverAddr->sa_family) ? "IPv4" : "IPv6");
+        LOG (GNUNET_ERROR_TYPE_ERROR,
+             _("`%s' failed for port %d (%s).\n"),
+             "bind",
+             port,
+             (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
       eno = 0;
     }
     else
       eno = 0;
     }
     else
@@ -491,12 +492,14 @@ open_listen_socket (const struct sockaddr *serverAddr, socklen_t socklen)
         LOG (GNUNET_ERROR_TYPE_WARNING,
              _("`%s' failed for port %d (%s): address already in use\n"),
              "bind", port,
         LOG (GNUNET_ERROR_TYPE_WARNING,
              _("`%s' failed for port %d (%s): address already in use\n"),
              "bind", port,
-             (AF_INET == serverAddr->sa_family) ? "IPv4" : "IPv6");
-      else if (AF_UNIX == serverAddr->sa_family)
+             (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
+      else if (AF_UNIX == server_addr->sa_family)
+      {
         LOG (GNUNET_ERROR_TYPE_WARNING,
         LOG (GNUNET_ERROR_TYPE_WARNING,
-             _("`%s' failed for `%s': address already in use\n"), "bind",
-             ((const struct sockaddr_un *) serverAddr)->sun_path);
-
+             _("`%s' failed for `%s': address already in use\n"),
+             "bind",
+             GNUNET_a2s (server_addr, socklen));
+      }
     }
     GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
     errno = eno;
     }
     GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
     errno = eno;
@@ -504,13 +507,15 @@ open_listen_socket (const struct sockaddr *serverAddr, socklen_t socklen)
   }
   if (GNUNET_OK != GNUNET_NETWORK_socket_listen (sock, 5))
   {
   }
   if (GNUNET_OK != GNUNET_NETWORK_socket_listen (sock, 5))
   {
-    LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "listen");
+    LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
+                  "listen");
     GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
     errno = 0;
     return NULL;
   }
   if (0 != port)
     GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
     errno = 0;
     return NULL;
   }
   if (0 != port)
-    LOG (GNUNET_ERROR_TYPE_DEBUG, "Server starts to listen on port %u.\n",
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Server starts to listen on port %u.\n",
          port);
   return sock;
 }
          port);
   return sock;
 }
@@ -519,32 +524,32 @@ open_listen_socket (const struct sockaddr *serverAddr, socklen_t socklen)
 /**
  * Create a new server.
  *
 /**
  * Create a new server.
  *
- * @param access function for access control
- * @param access_cls closure for access
+ * @param access_cb function for access control
+ * @param access_cb_cls closure for @a access_cb
  * @param lsocks NULL-terminated array of listen sockets
  * @param idle_timeout after how long should we timeout idle connections?
  * @param lsocks NULL-terminated array of listen sockets
  * @param idle_timeout after how long should we timeout idle connections?
- * @param require_found if YES, connections sending messages of unknown type
+ * @param require_found if #GNUNET_YES, connections sending messages of unknown type
  *        will be closed
  * @return handle for the new server, NULL on error
  *         (typically, "port" already in use)
  */
 struct GNUNET_SERVER_Handle *
  *        will be closed
  * @return handle for the new server, NULL on error
  *         (typically, "port" already in use)
  */
 struct GNUNET_SERVER_Handle *
-GNUNET_SERVER_create_with_sockets (GNUNET_CONNECTION_AccessCheck access,
-                                   void *access_cls,
+GNUNET_SERVER_create_with_sockets (GNUNET_CONNECTION_AccessCheck access_cb,
+                                   void *access_cb_cls,
                                    struct GNUNET_NETWORK_Handle **lsocks,
                                    struct GNUNET_TIME_Relative idle_timeout,
                                    int require_found)
 {
   struct GNUNET_SERVER_Handle *server;
 
                                    struct GNUNET_NETWORK_Handle **lsocks,
                                    struct GNUNET_TIME_Relative idle_timeout,
                                    int require_found)
 {
   struct GNUNET_SERVER_Handle *server;
 
-  server = GNUNET_malloc (sizeof (struct GNUNET_SERVER_Handle));
+  server = GNUNET_new (struct GNUNET_SERVER_Handle);
   server->idle_timeout = idle_timeout;
   server->listen_sockets = lsocks;
   server->idle_timeout = idle_timeout;
   server->listen_sockets = lsocks;
-  server->access = access;
-  server->access_cls = access_cls;
+  server->access_cb = access_cb;
+  server->access_cb_cls = access_cb_cls;
   server->require_found = require_found;
   if (NULL != lsocks)
   server->require_found = require_found;
   if (NULL != lsocks)
-    schedule_listen_task (server);
+    GNUNET_SERVER_resume (server);
   return server;
 }
 
   return server;
 }
 
@@ -552,10 +557,10 @@ GNUNET_SERVER_create_with_sockets (GNUNET_CONNECTION_AccessCheck access,
 /**
  * Create a new server.
  *
 /**
  * Create a new server.
  *
- * @param access function for access control
- * @param access_cls closure for access
- * @param serverAddr address to listen on (including port), NULL terminated array
- * @param socklen length of serverAddr
+ * @param access_cb function for access control
+ * @param access_cb_cls closure for @a access_cb
+ * @param server_addr address to listen on (including port), NULL terminated array
+ * @param socklen length of server_addr
  * @param idle_timeout after how long should we timeout idle connections?
  * @param require_found if YES, connections sending messages of unknown type
  *        will be closed
  * @param idle_timeout after how long should we timeout idle connections?
  * @param require_found if YES, connections sending messages of unknown type
  *        will be closed
@@ -563,8 +568,9 @@ GNUNET_SERVER_create_with_sockets (GNUNET_CONNECTION_AccessCheck access,
  *         (typically, "port" already in use)
  */
 struct GNUNET_SERVER_Handle *
  *         (typically, "port" already in use)
  */
 struct GNUNET_SERVER_Handle *
-GNUNET_SERVER_create (GNUNET_CONNECTION_AccessCheck access, void *access_cls,
-                      struct sockaddr *const *serverAddr,
+GNUNET_SERVER_create (GNUNET_CONNECTION_AccessCheck access_cb,
+                     void *access_cb_cls,
+                      struct sockaddr *const *server_addr,
                       const socklen_t * socklen,
                       struct GNUNET_TIME_Relative idle_timeout,
                       int require_found)
                       const socklen_t * socklen,
                       struct GNUNET_TIME_Relative idle_timeout,
                       int require_found)
@@ -576,19 +582,19 @@ GNUNET_SERVER_create (GNUNET_CONNECTION_AccessCheck access, void *access_cls,
   int seen;
 
   i = 0;
   int seen;
 
   i = 0;
-  while (NULL != serverAddr[i])
+  while (NULL != server_addr[i])
     i++;
   if (i > 0)
   {
     lsocks = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (i + 1));
     i = 0;
     j = 0;
     i++;
   if (i > 0)
   {
     lsocks = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (i + 1));
     i = 0;
     j = 0;
-    while (NULL != serverAddr[i])
+    while (NULL != server_addr[i])
     {
       seen = 0;
       for (k=0;k<i;k++)
        if ( (socklen[k] == socklen[i]) &&
     {
       seen = 0;
       for (k=0;k<i;k++)
        if ( (socklen[k] == socklen[i]) &&
-            (0 == memcmp (serverAddr[k], serverAddr[i], socklen[i])) )
+            (0 == memcmp (server_addr[k], server_addr[i], socklen[i])) )
        {
          seen = 1;
          break;
        {
          seen = 1;
          break;
@@ -599,7 +605,7 @@ GNUNET_SERVER_create (GNUNET_CONNECTION_AccessCheck access, void *access_cls,
        i++;
        continue;
       }
        i++;
        continue;
       }
-      lsocks[j] = open_listen_socket (serverAddr[i], socklen[i]);
+      lsocks[j] = open_listen_socket (server_addr[i], socklen[i]);
       if (NULL != lsocks[j])
         j++;
       i++;
       if (NULL != lsocks[j])
         j++;
       i++;
@@ -616,33 +622,38 @@ GNUNET_SERVER_create (GNUNET_CONNECTION_AccessCheck access, void *access_cls,
   {
     lsocks = NULL;
   }
   {
     lsocks = NULL;
   }
-  return GNUNET_SERVER_create_with_sockets (access, access_cls, lsocks,
-                                            idle_timeout, require_found);
+  return GNUNET_SERVER_create_with_sockets (access_cb,
+                                           access_cb_cls,
+                                           lsocks,
+                                            idle_timeout,
+                                           require_found);
 }
 
 
 /**
  * Set the 'monitor' flag on this client.  Clients which have been
  * marked as 'monitors' won't prevent the server from shutting down
 }
 
 
 /**
  * Set the 'monitor' flag on this client.  Clients which have been
  * marked as 'monitors' won't prevent the server from shutting down
- * once 'GNUNET_SERVER_stop_listening' has been invoked.  The idea is
+ * once '#GNUNET_SERVER_stop_listening()' has been invoked.  The idea is
  * that for "normal" clients we likely want to allow them to process
  * their requests; however, monitor-clients are likely to 'never'
  * disconnect during shutdown and thus will not be considered when
  * determining if the server should continue to exist after
  * that for "normal" clients we likely want to allow them to process
  * their requests; however, monitor-clients are likely to 'never'
  * disconnect during shutdown and thus will not be considered when
  * determining if the server should continue to exist after
- * 'GNUNET_SERVER_destroy' has been called.
+ * #GNUNET_SERVER_destroy() has been called.
  *
  * @param client the client to set the 'monitor' flag on
  */
 void
 GNUNET_SERVER_client_mark_monitor (struct GNUNET_SERVER_Client *client)
 {
  *
  * @param client the client to set the 'monitor' flag on
  */
 void
 GNUNET_SERVER_client_mark_monitor (struct GNUNET_SERVER_Client *client)
 {
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Marking client as monitor!\n");
   client->is_monitor = GNUNET_YES;
 }
 
 
 /**
   client->is_monitor = GNUNET_YES;
 }
 
 
 /**
- * Helper function for 'test_monitor_clients' to trigger
- * 'GNUNET_SERVER_destroy' after the stack has unwound.
+ * Helper function for #test_monitor_clients() to trigger
+ * #GNUNET_SERVER_destroy() after the stack has unwound.
  *
  * @param cls the 'struct GNUNET_SERVER_Handle' to destroy
  * @param tc unused
  *
  * @param cls the 'struct GNUNET_SERVER_Handle' to destroy
  * @param tc unused
@@ -652,6 +663,7 @@ do_destroy (void *cls,
            const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
   struct GNUNET_SERVER_Handle *server = cls;
            const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
   struct GNUNET_SERVER_Handle *server = cls;
+
   GNUNET_SERVER_destroy (server);
 }
 
   GNUNET_SERVER_destroy (server);
 }
 
@@ -673,8 +685,61 @@ test_monitor_clients (struct GNUNET_SERVER_Handle *server)
     if (GNUNET_NO == client->is_monitor)
       return; /* not done yet */
   server->in_soft_shutdown = GNUNET_SYSERR;
     if (GNUNET_NO == client->is_monitor)
       return; /* not done yet */
   server->in_soft_shutdown = GNUNET_SYSERR;
-  GNUNET_SCHEDULER_add_continuation (&do_destroy, server,
-                                    GNUNET_SCHEDULER_REASON_PREREQ_DONE);
+  GNUNET_SCHEDULER_add_now (&do_destroy, server);
+}
+
+
+/**
+ * Suspend accepting connections from the listen socket temporarily.
+ *
+ * @param server server to stop accepting connections.
+ */
+void
+GNUNET_SERVER_suspend (struct GNUNET_SERVER_Handle *server)
+{
+  if (NULL != server->listen_task)
+  {
+    GNUNET_SCHEDULER_cancel (server->listen_task);
+    server->listen_task = NULL;
+  }
+}
+
+
+/**
+ * Resume accepting connections from the listen socket.
+ *
+ * @param server server to stop accepting connections.
+ */
+void
+GNUNET_SERVER_resume (struct GNUNET_SERVER_Handle *server)
+{
+  struct GNUNET_NETWORK_FDSet *r;
+  unsigned int i;
+
+  if (NULL == server->listen_sockets)
+    return;
+  if (NULL == server->listen_sockets[0])
+    return; /* nothing to do, no listen sockets! */
+  if (NULL == server->listen_sockets[1])
+  {
+    /* simplified method: no fd set needed; this is then much simpler and
+       much more efficient */
+    server->listen_task =
+      GNUNET_SCHEDULER_add_read_net_with_priority (GNUNET_TIME_UNIT_FOREVER_REL,
+                                                  GNUNET_SCHEDULER_PRIORITY_HIGH,
+                                                  server->listen_sockets[0],
+                                                  &process_listen_socket, server);
+    return;
+  }
+  r = GNUNET_NETWORK_fdset_create ();
+  i = 0;
+  while (NULL != server->listen_sockets[i])
+    GNUNET_NETWORK_fdset_set (r, server->listen_sockets[i++]);
+  server->listen_task =
+    GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH,
+                                GNUNET_TIME_UNIT_FOREVER_REL, r, NULL,
+                                &process_listen_socket, server);
+  GNUNET_NETWORK_fdset_destroy (r);
 }
 
 
 }
 
 
@@ -689,11 +754,12 @@ GNUNET_SERVER_stop_listening (struct GNUNET_SERVER_Handle *server)
 {
   unsigned int i;
 
 {
   unsigned int i;
 
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "Server in soft shutdown\n");
-  if (GNUNET_SCHEDULER_NO_TASK != server->listen_task)
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Server in soft shutdown\n");
+  if (NULL != server->listen_task)
   {
     GNUNET_SCHEDULER_cancel (server->listen_task);
   {
     GNUNET_SCHEDULER_cancel (server->listen_task);
-    server->listen_task = GNUNET_SCHEDULER_NO_TASK;
+    server->listen_task = NULL;
   }
   if (NULL != server->listen_sockets)
   {
   }
   if (NULL != server->listen_sockets)
   {
@@ -722,11 +788,12 @@ GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *server)
   struct NotifyList *npos;
   unsigned int i;
 
   struct NotifyList *npos;
   unsigned int i;
 
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "Server shutting down.\n");
-  if (GNUNET_SCHEDULER_NO_TASK != server->listen_task)
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Server shutting down.\n");
+  if (NULL != server->listen_task)
   {
     GNUNET_SCHEDULER_cancel (server->listen_task);
   {
     GNUNET_SCHEDULER_cancel (server->listen_task);
-    server->listen_task = GNUNET_SCHEDULER_NO_TASK;
+    server->listen_task = NULL;
   }
   if (NULL != server->listen_sockets)
   {
   }
   if (NULL != server->listen_sockets)
   {
@@ -746,12 +813,22 @@ GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *server)
   }
   while (NULL != (npos = server->disconnect_notify_list_head))
   {
   }
   while (NULL != (npos = server->disconnect_notify_list_head))
   {
-    npos->callback (npos->callback_cls, NULL);
+    npos->callback (npos->callback_cls,
+                    NULL);
     GNUNET_CONTAINER_DLL_remove (server->disconnect_notify_list_head,
                                 server->disconnect_notify_list_tail,
                                 npos);
     GNUNET_free (npos);
   }
     GNUNET_CONTAINER_DLL_remove (server->disconnect_notify_list_head,
                                 server->disconnect_notify_list_tail,
                                 npos);
     GNUNET_free (npos);
   }
+  while (NULL != (npos = server->connect_notify_list_head))
+  {
+    npos->callback (npos->callback_cls,
+                    NULL);
+    GNUNET_CONTAINER_DLL_remove (server->connect_notify_list_head,
+                                server->connect_notify_list_tail,
+                                npos);
+    GNUNET_free (npos);
+  }
   GNUNET_free (server);
 }
 
   GNUNET_free (server);
 }
 
@@ -775,7 +852,7 @@ GNUNET_SERVER_add_handlers (struct GNUNET_SERVER_Handle *server,
 {
   struct HandlerList *p;
 
 {
   struct HandlerList *p;
 
-  p = GNUNET_malloc (sizeof (struct HandlerList));
+  p = GNUNET_new (struct HandlerList);
   p->handlers = handlers;
   p->next = server->handlers;
   server->handlers = p;
   p->handlers = handlers;
   p->next = server->handlers;
   server->handlers = p;
@@ -790,7 +867,7 @@ GNUNET_SERVER_add_handlers (struct GNUNET_SERVER_Handle *server,
  * @param create new tokenizer initialization function
  * @param destroy new tokenizer destruction function
  * @param receive new tokenizer receive function
  * @param create new tokenizer initialization function
  * @param destroy new tokenizer destruction function
  * @param receive new tokenizer receive function
- * @param cls closure for 'create', 'receive', 'destroy' 
+ * @param cls closure for @a create, @a receive, @a destroy
  */
 void
 GNUNET_SERVER_set_callbacks (struct GNUNET_SERVER_Handle *server,
  */
 void
 GNUNET_SERVER_set_callbacks (struct GNUNET_SERVER_Handle *server,
@@ -807,27 +884,26 @@ GNUNET_SERVER_set_callbacks (struct GNUNET_SERVER_Handle *server,
 
 
 /**
 
 
 /**
- * Task run to warn about missing calls to 'GNUNET_SERVER_receive_done'.
+ * Task run to warn about missing calls to #GNUNET_SERVER_receive_done.
  *
  *
- * @param cls our 'struct GNUNET_SERVER_Client*' to process more requests from
+ * @param cls our `struct GNUNET_SERVER_Client *` to process more requests from
  * @param tc scheduler context (unused)
  */
 static void
  * @param tc scheduler context (unused)
  */
 static void
-warn_no_receive_done (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+warn_no_receive_done (void *cls,
+                     const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
   struct GNUNET_SERVER_Client *client = cls;
 
   GNUNET_break (0 != client->warn_type); /* type should never be 0 here, as we don't use 0 */
   client->warn_task =
 {
   struct GNUNET_SERVER_Client *client = cls;
 
   GNUNET_break (0 != client->warn_type); /* type should never be 0 here, as we don't use 0 */
   client->warn_task =
-      GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
+      GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
                                     &warn_no_receive_done, client);
   if (0 == (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
     LOG (GNUNET_ERROR_TYPE_WARNING,
                                     &warn_no_receive_done, client);
   if (0 == (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
     LOG (GNUNET_ERROR_TYPE_WARNING,
-         _
-         ("Processing code for message of type %u did not call GNUNET_SERVER_receive_done after %llums\n"),
+         _("Processing code for message of type %u did not call `GNUNET_SERVER_receive_done' after %s\n"),
          (unsigned int) client->warn_type,
          (unsigned int) client->warn_type,
-         (unsigned long long)
-         GNUNET_TIME_absolute_get_duration (client->warn_start).rel_value);
+         GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (client->warn_start), GNUNET_YES));
 }
 
 
 }
 
 
@@ -841,10 +917,10 @@ warn_no_receive_done (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 void
 GNUNET_SERVER_disable_receive_done_warning (struct GNUNET_SERVER_Client *client)
 {
 void
 GNUNET_SERVER_disable_receive_done_warning (struct GNUNET_SERVER_Client *client)
 {
-  if (GNUNET_SCHEDULER_NO_TASK != client->warn_task)
+  if (NULL != client->warn_task)
   {
     GNUNET_SCHEDULER_cancel (client->warn_task);
   {
     GNUNET_SCHEDULER_cancel (client->warn_task);
-    client->warn_task = GNUNET_SCHEDULER_NO_TASK;
+    client->warn_task = NULL;
   }
 }
 
   }
 }
 
@@ -859,9 +935,9 @@ GNUNET_SERVER_disable_receive_done_warning (struct GNUNET_SERVER_Client *client)
  * @param sender the "pretended" sender of the message
  *        can be NULL!
  * @param message message to transmit
  * @param sender the "pretended" sender of the message
  *        can be NULL!
  * @param message message to transmit
- * @return GNUNET_OK if the message was OK and the
+ * @return #GNUNET_OK if the message was OK and the
  *                   connection can stay open
  *                   connection can stay open
- *         GNUNET_SYSERR if the connection to the
+ *         #GNUNET_SYSERR if the connection to the
  *         client should be shut down
  */
 int
  *         client should be shut down
  */
 int
@@ -897,17 +973,22 @@ GNUNET_SERVER_inject (struct GNUNET_SERVER_Handle *server,
                "Expected %u bytes for message of type %u, got %u\n",
                mh->expected_size, mh->type, size);
           GNUNET_break_op (0);
                "Expected %u bytes for message of type %u, got %u\n",
                mh->expected_size, mh->type, size);
           GNUNET_break_op (0);
+#else
+          LOG (GNUNET_ERROR_TYPE_DEBUG,
+               "Expected %u bytes for message of type %u, got %u\n",
+               mh->expected_size, mh->type, size);
 #endif
           return GNUNET_SYSERR;
         }
         if (NULL != sender)
         {
 #endif
           return GNUNET_SYSERR;
         }
         if (NULL != sender)
         {
-          if (0 == sender->suspended)
+          if ( (0 == sender->suspended) &&
+              (NULL == sender->warn_task) )
           {
            GNUNET_break (0 != type); /* type should never be 0 here, as we don't use 0 */
             sender->warn_start = GNUNET_TIME_absolute_get ();
             sender->warn_task =
           {
            GNUNET_break (0 != type); /* type should never be 0 here, as we don't use 0 */
             sender->warn_start = GNUNET_TIME_absolute_get ();
             sender->warn_task =
-                GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
+                GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
                                               &warn_no_receive_done, sender);
             sender->warn_type = type;
           }
                                               &warn_no_receive_done, sender);
             sender->warn_type = type;
           }
@@ -937,12 +1018,16 @@ GNUNET_SERVER_inject (struct GNUNET_SERVER_Handle *server,
  * @param buf buffer with data received from network
  * @param available number of bytes available in buf
  * @param addr address of the sender
  * @param buf buffer with data received from network
  * @param available number of bytes available in buf
  * @param addr address of the sender
- * @param addrlen length of addr
+ * @param addrlen length of @a addr
  * @param errCode code indicating errors receiving, 0 for success
  */
 static void
  * @param errCode code indicating errors receiving, 0 for success
  */
 static void
-process_incoming (void *cls, const void *buf, size_t available,
-                  const struct sockaddr *addr, socklen_t addrlen, int errCode);
+process_incoming (void *cls,
+                  const void *buf,
+                  size_t available,
+                  const struct sockaddr *addr,
+                  socklen_t addrlen,
+                  int errCode);
 
 
 /**
 
 
 /**
@@ -952,14 +1037,15 @@ process_incoming (void *cls, const void *buf, size_t available,
  * or shutdown.
  *
  * @param client the client to process, RC must have already been increased
  * or shutdown.
  *
  * @param client the client to process, RC must have already been increased
- *        using GNUNET_SERVER_client_keep and will be decreased by one in this
+ *        using #GNUNET_SERVER_client_keep and will be decreased by one in this
  *        function
  *        function
- * @param ret GNUNET_NO to start processing from the buffer,
- *            GNUNET_OK if the mst buffer is drained and we should instantly go back to receiving
- *            GNUNET_SYSERR if we should instantly abort due to error in a previous step
+ * @param ret #GNUNET_NO to start processing from the buffer,
+ *            #GNUNET_OK if the mst buffer is drained and we should instantly go back to receiving
+ *            #GNUNET_SYSERR if we should instantly abort due to error in a previous step
  */
 static void
  */
 static void
-process_mst (struct GNUNET_SERVER_Client *client, int ret)
+process_mst (struct GNUNET_SERVER_Client *client,
+             int ret)
 {
   while ((GNUNET_SYSERR != ret) && (NULL != client->server) &&
          (GNUNET_YES != client->shutdown_now) && (0 == client->suspended))
 {
   while ((GNUNET_SYSERR != ret) && (NULL != client->server) &&
          (GNUNET_YES != client->shutdown_now) && (0 == client->suspended))
@@ -967,12 +1053,13 @@ process_mst (struct GNUNET_SERVER_Client *client, int ret)
     if (GNUNET_OK == ret)
     {
       LOG (GNUNET_ERROR_TYPE_DEBUG,
     if (GNUNET_OK == ret)
     {
       LOG (GNUNET_ERROR_TYPE_DEBUG,
-           "Server re-enters receive loop, timeout: %llu.\n",
-           client->idle_timeout.rel_value);
+           "Server re-enters receive loop, timeout: %s.\n",
+           GNUNET_STRINGS_relative_time_to_string (client->idle_timeout, GNUNET_YES));
       client->receive_pending = GNUNET_YES;
       GNUNET_CONNECTION_receive (client->connection,
                                  GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
       client->receive_pending = GNUNET_YES;
       GNUNET_CONNECTION_receive (client->connection,
                                  GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
-                                 client->idle_timeout, &process_incoming,
+                                 client->idle_timeout,
+                                 &process_incoming,
                                  client);
       break;
     }
                                  client);
       break;
     }
@@ -989,14 +1076,17 @@ process_mst (struct GNUNET_SERVER_Client *client, int ret)
   }
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Server leaves instant processing loop: ret = %d, server = %p, shutdown = %d, suspended = %u\n",
   }
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Server leaves instant processing loop: ret = %d, server = %p, shutdown = %d, suspended = %u\n",
-       ret, client->server, client->shutdown_now, client->suspended);
+       ret, client->server,
+       client->shutdown_now,
+       client->suspended);
   if (GNUNET_NO == ret)
   {
     LOG (GNUNET_ERROR_TYPE_DEBUG,
          "Server has more data pending but is suspended.\n");
     client->receive_pending = GNUNET_SYSERR;    /* data pending */
   }
   if (GNUNET_NO == ret)
   {
     LOG (GNUNET_ERROR_TYPE_DEBUG,
          "Server has more data pending but is suspended.\n");
     client->receive_pending = GNUNET_SYSERR;    /* data pending */
   }
-  if ((GNUNET_SYSERR == ret) || (GNUNET_YES == client->shutdown_now))
+  if ( (GNUNET_SYSERR == ret) ||
+       (GNUNET_YES == client->shutdown_now) )
     GNUNET_SERVER_client_disconnect (client);
 }
 
     GNUNET_SERVER_client_disconnect (client);
 }
 
@@ -1008,12 +1098,16 @@ process_mst (struct GNUNET_SERVER_Client *client, int ret)
  * @param buf buffer with data received from network
  * @param available number of bytes available in buf
  * @param addr address of the sender
  * @param buf buffer with data received from network
  * @param available number of bytes available in buf
  * @param addr address of the sender
- * @param addrlen length of addr
+ * @param addrlen length of @a addr
  * @param errCode code indicating errors receiving, 0 for success
  */
 static void
  * @param errCode code indicating errors receiving, 0 for success
  */
 static void
-process_incoming (void *cls, const void *buf, size_t available,
-                  const struct sockaddr *addr, socklen_t addrlen, int errCode)
+process_incoming (void *cls,
+                  const void *buf,
+                  size_t available,
+                  const struct sockaddr *addr,
+                  socklen_t addrlen,
+                  int errCode)
 {
   struct GNUNET_SERVER_Client *client = cls;
   struct GNUNET_SERVER_Handle *server = client->server;
 {
   struct GNUNET_SERVER_Client *client = cls;
   struct GNUNET_SERVER_Handle *server = client->server;
@@ -1024,45 +1118,69 @@ process_incoming (void *cls, const void *buf, size_t available,
   GNUNET_assert (GNUNET_YES == client->receive_pending);
   client->receive_pending = GNUNET_NO;
   now = GNUNET_TIME_absolute_get ();
   GNUNET_assert (GNUNET_YES == client->receive_pending);
   client->receive_pending = GNUNET_NO;
   now = GNUNET_TIME_absolute_get ();
-  end = GNUNET_TIME_absolute_add (client->last_activity, client->idle_timeout);
-
-  if ((NULL == buf) && (0 == available) && (NULL == addr) && (0 == errCode) &&
-      (GNUNET_YES != client->shutdown_now) && (NULL != server) &&
-      (GNUNET_YES == GNUNET_CONNECTION_check (client->connection)) &&
-      (end.abs_value > now.abs_value))
+  end = GNUNET_TIME_absolute_add (client->last_activity,
+                                  client->idle_timeout);
+
+  if ( (NULL == buf) &&
+       (0 == available) &&
+       (NULL == addr) &&
+       (0 == errCode) &&
+       (GNUNET_YES != client->shutdown_now) &&
+       (NULL != server) &&
+       (GNUNET_YES == GNUNET_CONNECTION_check (client->connection)) &&
+       (end.abs_value_us > now.abs_value_us) )
   {
     /* wait longer, timeout changed (i.e. due to us sending) */
     LOG (GNUNET_ERROR_TYPE_DEBUG,
          "Receive time out, but no disconnect due to sending (%p)\n",
   {
     /* wait longer, timeout changed (i.e. due to us sending) */
     LOG (GNUNET_ERROR_TYPE_DEBUG,
          "Receive time out, but no disconnect due to sending (%p)\n",
-         GNUNET_a2s (addr, addrlen));
+         client);
     client->receive_pending = GNUNET_YES;
     GNUNET_CONNECTION_receive (client->connection,
                                GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
                                GNUNET_TIME_absolute_get_remaining (end),
     client->receive_pending = GNUNET_YES;
     GNUNET_CONNECTION_receive (client->connection,
                                GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
                                GNUNET_TIME_absolute_get_remaining (end),
-                               &process_incoming, client);
+                               &process_incoming,
+                               client);
     return;
   }
     return;
   }
-  if ((NULL == buf) || (0 == available) || (0 != errCode) || (NULL == server) ||
-      (GNUNET_YES == client->shutdown_now) ||
-      (GNUNET_YES != GNUNET_CONNECTION_check (client->connection)))
+  if ( (NULL == buf) ||
+       (0 == available) ||
+       (0 != errCode) ||
+       (NULL == server) ||
+       (GNUNET_YES == client->shutdown_now) ||
+       (GNUNET_YES != GNUNET_CONNECTION_check (client->connection)) )
   {
     /* other side closed connection, error connecting, etc. */
   {
     /* other side closed connection, error connecting, etc. */
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Failed to connect or other side closed connection (%p)\n",
+         client);
     GNUNET_SERVER_client_disconnect (client);
     return;
   }
     GNUNET_SERVER_client_disconnect (client);
     return;
   }
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "Server receives %u bytes from `%s'.\n",
-       (unsigned int) available, GNUNET_a2s (addr, addrlen));
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Server receives %u bytes from `%s'.\n",
+       (unsigned int) available,
+       GNUNET_a2s (addr, addrlen));
   GNUNET_SERVER_client_keep (client);
   client->last_activity = now;
 
   if (NULL != server->mst_receive)
   GNUNET_SERVER_client_keep (client);
   client->last_activity = now;
 
   if (NULL != server->mst_receive)
-    ret =
-        client->server->mst_receive (client->server->mst_cls, client->mst,
-                                     client, buf, available, GNUNET_NO, GNUNET_YES);
+  {
+    ret = client->server->mst_receive (client->server->mst_cls,
+                                       client->mst,
+                                       client,
+                                       buf,
+                                       available,
+                                       GNUNET_NO,
+                                       GNUNET_YES);
+  }
   else if (NULL != client->mst)
   {
     ret =
   else if (NULL != client->mst)
   {
     ret =
-        GNUNET_SERVER_mst_receive (client->mst, client, buf, available, GNUNET_NO,
+        GNUNET_SERVER_mst_receive (client->mst,
+                                   client,
+                                   buf,
+                                   available,
+                                   GNUNET_NO,
                                    GNUNET_YES);
   }
   else
                                    GNUNET_YES);
   }
   else
@@ -1070,8 +1188,8 @@ process_incoming (void *cls, const void *buf, size_t available,
     GNUNET_break (0);
     return;
   }
     GNUNET_break (0);
     return;
   }
-
-  process_mst (client, ret);
+  process_mst (client,
+               ret);
   GNUNET_SERVER_client_drop (client);
 }
 
   GNUNET_SERVER_client_drop (client);
 }
 
@@ -1080,30 +1198,34 @@ process_incoming (void *cls, const void *buf, size_t available,
  * Task run to start again receiving from the network
  * and process requests.
  *
  * Task run to start again receiving from the network
  * and process requests.
  *
- * @param cls our 'struct GNUNET_SERVER_Client*' to process more requests from
+ * @param cls our `struct GNUNET_SERVER_Client *` to process more requests from
  * @param tc scheduler context (unused)
  */
 static void
  * @param tc scheduler context (unused)
  */
 static void
-restart_processing (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+restart_processing (void *cls,
+                    const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
   struct GNUNET_SERVER_Client *client = cls;
 
   GNUNET_assert (GNUNET_YES != client->shutdown_now);
 {
   struct GNUNET_SERVER_Client *client = cls;
 
   GNUNET_assert (GNUNET_YES != client->shutdown_now);
-  client->restart_task = GNUNET_SCHEDULER_NO_TASK;
+  client->restart_task = NULL;
   if (GNUNET_NO == client->receive_pending)
   {
     LOG (GNUNET_ERROR_TYPE_DEBUG, "Server begins to read again from client.\n");
     client->receive_pending = GNUNET_YES;
     GNUNET_CONNECTION_receive (client->connection,
                                GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
   if (GNUNET_NO == client->receive_pending)
   {
     LOG (GNUNET_ERROR_TYPE_DEBUG, "Server begins to read again from client.\n");
     client->receive_pending = GNUNET_YES;
     GNUNET_CONNECTION_receive (client->connection,
                                GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
-                               client->idle_timeout, &process_incoming, client);
+                               client->idle_timeout,
+                               &process_incoming,
+                               client);
     return;
   }
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Server continues processing messages still in the buffer.\n");
   GNUNET_SERVER_client_keep (client);
   client->receive_pending = GNUNET_NO;
     return;
   }
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Server continues processing messages still in the buffer.\n");
   GNUNET_SERVER_client_keep (client);
   client->receive_pending = GNUNET_NO;
-  process_mst (client, GNUNET_NO);
+  process_mst (client,
+               GNUNET_NO);
   GNUNET_SERVER_client_drop (client);
 }
 
   GNUNET_SERVER_client_drop (client);
 }
 
@@ -1113,13 +1235,14 @@ restart_processing (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
  * received a complete message.
  *
  * @param cls closure (struct GNUNET_SERVER_Handle)
  * received a complete message.
  *
  * @param cls closure (struct GNUNET_SERVER_Handle)
- * @param client identification of the client (struct GNUNET_SERVER_Client*)
+ * @param client identification of the client (`struct GNUNET_SERVER_Client *`)
  * @param message the actual message
  *
  * @param message the actual message
  *
- * @return GNUNET_OK on success, GNUNET_SYSERR to stop further processing
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR to stop further processing
  */
 static int
  */
 static int
-client_message_tokenizer_callback (void *cls, void *client,
+client_message_tokenizer_callback (void *cls,
+                                   void *client,
                                    const struct GNUNET_MessageHeader *message)
 {
   struct GNUNET_SERVER_Handle *server = cls;
                                    const struct GNUNET_MessageHeader *message)
 {
   struct GNUNET_SERVER_Handle *server = cls;
@@ -1150,18 +1273,17 @@ client_message_tokenizer_callback (void *cls, void *client,
  * @param server the server to use
  * @param connection the connection to manage (client must
  *        stop using this connection from now on)
  * @param server the server to use
  * @param connection the connection to manage (client must
  *        stop using this connection from now on)
- * @return the client handle (client should call
- *         "client_drop" on the return value eventually)
+ * @return the client handle
  */
 struct GNUNET_SERVER_Client *
 GNUNET_SERVER_connect_socket (struct GNUNET_SERVER_Handle *server,
                               struct GNUNET_CONNECTION_Handle *connection)
 {
   struct GNUNET_SERVER_Client *client;
  */
 struct GNUNET_SERVER_Client *
 GNUNET_SERVER_connect_socket (struct GNUNET_SERVER_Handle *server,
                               struct GNUNET_CONNECTION_Handle *connection)
 {
   struct GNUNET_SERVER_Client *client;
+  struct NotifyList *n;
 
 
-  client = GNUNET_malloc (sizeof (struct GNUNET_SERVER_Client));
+  client = GNUNET_new (struct GNUNET_SERVER_Client);
   client->connection = connection;
   client->connection = connection;
-  client->reference_count = 1;
   client->server = server;
   client->last_activity = GNUNET_TIME_absolute_get ();
   client->idle_timeout = server->idle_timeout;
   client->server = server;
   client->last_activity = GNUNET_TIME_absolute_get ();
   client->idle_timeout = server->idle_timeout;
@@ -1173,12 +1295,17 @@ GNUNET_SERVER_connect_socket (struct GNUNET_SERVER_Handle *server,
         server->mst_create (server->mst_cls, client);
   else
     client->mst =
         server->mst_create (server->mst_cls, client);
   else
     client->mst =
-        GNUNET_SERVER_mst_create (&client_message_tokenizer_callback, server);
+        GNUNET_SERVER_mst_create (&client_message_tokenizer_callback,
+                                  server);
   GNUNET_assert (NULL != client->mst);
   GNUNET_assert (NULL != client->mst);
+  for (n = server->connect_notify_list_head; NULL != n; n = n->next)
+    n->callback (n->callback_cls, client);
   client->receive_pending = GNUNET_YES;
   GNUNET_CONNECTION_receive (client->connection,
                              GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
   client->receive_pending = GNUNET_YES;
   GNUNET_CONNECTION_receive (client->connection,
                              GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
-                             client->idle_timeout, &process_incoming, client);
+                             client->idle_timeout,
+                             &process_incoming,
+                             client);
   return client;
 }
 
   return client;
 }
 
@@ -1236,8 +1363,8 @@ GNUNET_SERVER_client_drop (struct GNUNET_SERVER_Client *client)
  *
  * @param client the client to get the address for
  * @param addr where to store the address
  *
  * @param client the client to get the address for
  * @param addr where to store the address
- * @param addrlen where to store the length of the address
- * @return GNUNET_OK on success
+ * @param addrlen where to store the length of the @a addr
+ * @return #GNUNET_OK on success
  */
 int
 GNUNET_SERVER_client_get_address (struct GNUNET_SERVER_Client *client,
  */
 int
 GNUNET_SERVER_client_get_address (struct GNUNET_SERVER_Client *client,
@@ -1255,7 +1382,7 @@ GNUNET_SERVER_client_get_address (struct GNUNET_SERVER_Client *client,
  *
  * @param server the server manageing the clients
  * @param callback function to call on disconnect
  *
  * @param server the server manageing the clients
  * @param callback function to call on disconnect
- * @param callback_cls closure for callback
+ * @param callback_cls closure for @a callback
  */
 void
 GNUNET_SERVER_disconnect_notify (struct GNUNET_SERVER_Handle *server,
  */
 void
 GNUNET_SERVER_disconnect_notify (struct GNUNET_SERVER_Handle *server,
@@ -1264,7 +1391,7 @@ GNUNET_SERVER_disconnect_notify (struct GNUNET_SERVER_Handle *server,
 {
   struct NotifyList *n;
 
 {
   struct NotifyList *n;
 
-  n = GNUNET_malloc (sizeof (struct NotifyList));
+  n = GNUNET_new (struct NotifyList);
   n->callback = callback;
   n->callback_cls = callback_cls;
   GNUNET_CONTAINER_DLL_insert (server->disconnect_notify_list_head,
   n->callback = callback;
   n->callback_cls = callback_cls;
   GNUNET_CONTAINER_DLL_insert (server->disconnect_notify_list_head,
@@ -1274,16 +1401,48 @@ GNUNET_SERVER_disconnect_notify (struct GNUNET_SERVER_Handle *server,
 
 
 /**
 
 
 /**
- * Ask the server to stop notifying us whenever a client disconnects.
+ * Ask the server to notify us whenever a client connects.
+ * This function is called whenever the actual network connection
+ * is opened. If the server is destroyed before this
+ * notification is explicitly cancelled, the 'callback' will
+ * once be called with a 'client' argument of NULL to indicate
+ * that the server itself is now gone (and that the callback
+ * won't be called anymore and also can no longer be cancelled).
  *
  * @param server the server manageing the clients
  *
  * @param server the server manageing the clients
- * @param callback function to call on disconnect
- * @param callback_cls closure for callback
+ * @param callback function to call on sconnect
+ * @param callback_cls closure for @a callback
+ */
+void
+GNUNET_SERVER_connect_notify (struct GNUNET_SERVER_Handle *server,
+                             GNUNET_SERVER_ConnectCallback callback,
+                             void *callback_cls)
+{
+  struct NotifyList *n;
+  struct GNUNET_SERVER_Client *client;
+
+  n = GNUNET_new (struct NotifyList);
+  n->callback = callback;
+  n->callback_cls = callback_cls;
+  GNUNET_CONTAINER_DLL_insert (server->connect_notify_list_head,
+                              server->connect_notify_list_tail,
+                              n);
+  for (client = server->clients_head; NULL != client; client = client->next)
+    callback (callback_cls, client);
+}
+
+
+/**
+ * Ask the server to stop notifying us whenever a client connects.
+ *
+ * @param server the server manageing the clients
+ * @param callback function to call on connect
+ * @param callback_cls closure for @a callback
  */
 void
 GNUNET_SERVER_disconnect_notify_cancel (struct GNUNET_SERVER_Handle *server,
  */
 void
 GNUNET_SERVER_disconnect_notify_cancel (struct GNUNET_SERVER_Handle *server,
-                                        GNUNET_SERVER_DisconnectCallback
-                                        callback, void *callback_cls)
+                                        GNUNET_SERVER_DisconnectCallback callback,
+                                        void *callback_cls)
 {
   struct NotifyList *pos;
 
 {
   struct NotifyList *pos;
 
@@ -1303,9 +1462,38 @@ GNUNET_SERVER_disconnect_notify_cancel (struct GNUNET_SERVER_Handle *server,
 
 
 /**
 
 
 /**
- * Destroy the connection that is passed in via 'cls'.  Used
- * as calling 'GNUNET_CONNECTION_destroy' from within a function
- * that was itself called from within 'process_notify' of
+ * Ask the server to stop notifying us whenever a client disconnects.
+ *
+ * @param server the server manageing the clients
+ * @param callback function to call on disconnect
+ * @param callback_cls closure for @a callback
+ */
+void
+GNUNET_SERVER_connect_notify_cancel (struct GNUNET_SERVER_Handle *server,
+                                    GNUNET_SERVER_ConnectCallback callback,
+                                    void *callback_cls)
+{
+  struct NotifyList *pos;
+
+  for (pos = server->connect_notify_list_head; NULL != pos; pos = pos->next)
+    if ((pos->callback == callback) && (pos->callback_cls == callback_cls))
+      break;
+  if (NULL == pos)
+  {
+    GNUNET_break (0);
+    return;
+  }
+  GNUNET_CONTAINER_DLL_remove (server->connect_notify_list_head,
+                              server->connect_notify_list_tail,
+                              pos);
+  GNUNET_free (pos);
+}
+
+
+/**
+ * Destroy the connection that is passed in via @a cls.  Used
+ * as calling #GNUNET_CONNECTION_destroy from within a function
+ * that was itself called from within process_notify() of
  * 'connection.c' is not allowed (see #2329).
  *
  * @param cls connection to destroy
  * 'connection.c' is not allowed (see #2329).
  *
  * @param cls connection to destroy
@@ -1316,14 +1504,14 @@ destroy_connection (void *cls,
                    const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
   struct GNUNET_CONNECTION_Handle *connection = cls;
                    const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
   struct GNUNET_CONNECTION_Handle *connection = cls;
-  
+
   GNUNET_CONNECTION_destroy (connection);
 }
 
 
 /**
  * Ask the server to disconnect from the given client.
   GNUNET_CONNECTION_destroy (connection);
 }
 
 
 /**
  * Ask the server to disconnect from the given client.
- * This is the same as returning GNUNET_SYSERR from a message
+ * This is the same as returning #GNUNET_SYSERR from a message
  * handler, except that it allows dropping of a client even
  * when not handling a message from that client.
  *
  * handler, except that it allows dropping of a client even
  * when not handling a message from that client.
  *
@@ -1337,22 +1525,22 @@ GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client)
 
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Client is being disconnected from the server.\n");
 
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Client is being disconnected from the server.\n");
-  if (GNUNET_SCHEDULER_NO_TASK != client->restart_task)
+  if (NULL != client->restart_task)
   {
     GNUNET_SCHEDULER_cancel (client->restart_task);
   {
     GNUNET_SCHEDULER_cancel (client->restart_task);
-    client->restart_task = GNUNET_SCHEDULER_NO_TASK;
+    client->restart_task = NULL;
   }
   }
-  if (GNUNET_SCHEDULER_NO_TASK != client->warn_task)
+  if (NULL != client->warn_task)
   {
     GNUNET_SCHEDULER_cancel (client->warn_task);
   {
     GNUNET_SCHEDULER_cancel (client->warn_task);
-    client->warn_task = GNUNET_SCHEDULER_NO_TASK;
+    client->warn_task = NULL;
   }
   if (GNUNET_YES == client->receive_pending)
   {
     GNUNET_CONNECTION_receive_cancel (client->connection);
     client->receive_pending = GNUNET_NO;
   }
   }
   if (GNUNET_YES == client->receive_pending)
   {
     GNUNET_CONNECTION_receive_cancel (client->connection);
     client->receive_pending = GNUNET_NO;
   }
-  client->shutdown_now = GNUNET_YES;    
+  client->shutdown_now = GNUNET_YES;
   client->reference_count++; /* make sure nobody else clean up client... */
   if ( (NULL != client->mst) &&
        (NULL != server) )
   client->reference_count++; /* make sure nobody else clean up client... */
   if ( (NULL != client->mst) &&
        (NULL != server) )
@@ -1361,35 +1549,52 @@ GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client)
                                 server->clients_tail,
                                 client);
     if (NULL != server->mst_destroy)
                                 server->clients_tail,
                                 client);
     if (NULL != server->mst_destroy)
-      server->mst_destroy (server->mst_cls, client->mst);
+      server->mst_destroy (server->mst_cls,
+                           client->mst);
     else
       GNUNET_SERVER_mst_destroy (client->mst);
     client->mst = NULL;
     for (n = server->disconnect_notify_list_head; NULL != n; n = n->next)
     else
       GNUNET_SERVER_mst_destroy (client->mst);
     client->mst = NULL;
     for (n = server->disconnect_notify_list_head; NULL != n; n = n->next)
-      n->callback (n->callback_cls, client);
+      n->callback (n->callback_cls,
+                   client);
   }
   client->reference_count--;
   if (client->reference_count > 0)
   {
     LOG (GNUNET_ERROR_TYPE_DEBUG,
   }
   client->reference_count--;
   if (client->reference_count > 0)
   {
     LOG (GNUNET_ERROR_TYPE_DEBUG,
-         "RC still positive, not destroying everything.\n");
+         "RC of %p still positive, not destroying everything.\n",
+         client);
     client->server = NULL;
     return;
   }
   if (GNUNET_YES == client->in_process_client_buffer)
   {
     LOG (GNUNET_ERROR_TYPE_DEBUG,
     client->server = NULL;
     return;
   }
   if (GNUNET_YES == client->in_process_client_buffer)
   {
     LOG (GNUNET_ERROR_TYPE_DEBUG,
-         "Still processing inputs, not destroying everything.\n");
+         "Still processing inputs of %p, not destroying everything.\n",
+         client);
     return;
   }
     return;
   }
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "RC of %p now zero, destroying everything.\n",
+       client);
   if (GNUNET_YES == client->persist)
     GNUNET_CONNECTION_persist_ (client->connection);
   if (NULL != client->th.cth)
     GNUNET_SERVER_notify_transmit_ready_cancel (&client->th);
   (void) GNUNET_SCHEDULER_add_now (&destroy_connection,
                                   client->connection);
   if (GNUNET_YES == client->persist)
     GNUNET_CONNECTION_persist_ (client->connection);
   if (NULL != client->th.cth)
     GNUNET_SERVER_notify_transmit_ready_cancel (&client->th);
   (void) GNUNET_SCHEDULER_add_now (&destroy_connection,
                                   client->connection);
-  GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == client->warn_task);
-  GNUNET_assert (GNUNET_NO == client->receive_pending);
+  /* need to cancel again, as it might have been re-added
+     in the meantime (i.e. during callbacks) */
+  if (NULL != client->warn_task)
+  {
+    GNUNET_SCHEDULER_cancel (client->warn_task);
+    client->warn_task = NULL;
+  }
+  if (GNUNET_YES == client->receive_pending)
+  {
+    GNUNET_CONNECTION_receive_cancel (client->connection);
+    client->receive_pending = GNUNET_NO;
+  }
   GNUNET_free (client);
   /* we might be in soft-shutdown, test if we're done */
   if (NULL != server)
   GNUNET_free (client);
   /* we might be in soft-shutdown, test if we're done */
   if (NULL != server)
@@ -1403,7 +1608,7 @@ GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client)
  * instead of potentially buffering multiple messages.
  *
  * @param client handle to the client
  * instead of potentially buffering multiple messages.
  *
  * @param client handle to the client
- * @return GNUNET_OK on success
+ * @return #GNUNET_OK on success
  */
 int
 GNUNET_SERVER_client_disable_corking (struct GNUNET_SERVER_Client *client)
  */
 int
 GNUNET_SERVER_client_disable_corking (struct GNUNET_SERVER_Client *client)
@@ -1416,7 +1621,7 @@ GNUNET_SERVER_client_disable_corking (struct GNUNET_SERVER_Client *client)
  * Wrapper for transmission notification that calls the original
  * callback and update the last activity time for our connection.
  *
  * Wrapper for transmission notification that calls the original
  * callback and update the last activity time for our connection.
  *
- * @param cls the 'struct GNUNET_SERVER_Client'
+ * @param cls the `struct GNUNET_SERVER_Client *`
  * @param size number of bytes we can transmit
  * @param buf where to copy the message
  * @return number of bytes actually transmitted
  * @param size number of bytes we can transmit
  * @param buf where to copy the message
  * @return number of bytes actually transmitted
@@ -1444,18 +1649,18 @@ transmit_ready_callback_wrapper (void *cls, size_t size, void *buf)
  * @param timeout after how long should we give up (and call
  *        notify with buf NULL and size 0)?
  * @param callback function to call when space is available
  * @param timeout after how long should we give up (and call
  *        notify with buf NULL and size 0)?
  * @param callback function to call when space is available
- * @param callback_cls closure for callback
+ * @param callback_cls closure for @a callback
  * @return non-NULL if the notify callback was queued; can be used
  * @return non-NULL if the notify callback was queued; can be used
- *           to cancel the request using
- *           GNUNET_SERVER_notify_transmit_ready_cancel.
+ *         to cancel the request using
+ *         #GNUNET_SERVER_notify_transmit_ready_cancel().
  *         NULL if we are already going to notify someone else (busy)
  */
 struct GNUNET_SERVER_TransmitHandle *
 GNUNET_SERVER_notify_transmit_ready (struct GNUNET_SERVER_Client *client,
                                      size_t size,
                                      struct GNUNET_TIME_Relative timeout,
  *         NULL if we are already going to notify someone else (busy)
  */
 struct GNUNET_SERVER_TransmitHandle *
 GNUNET_SERVER_notify_transmit_ready (struct GNUNET_SERVER_Client *client,
                                      size_t size,
                                      struct GNUNET_TIME_Relative timeout,
-                                     GNUNET_CONNECTION_TransmitReadyNotify
-                                     callback, void *callback_cls)
+                                     GNUNET_CONNECTION_TransmitReadyNotify callback,
+                                     void *callback_cls)
 {
   if (NULL != client->th.callback)
     return NULL;
 {
   if (NULL != client->th.callback)
     return NULL;
@@ -1502,14 +1707,15 @@ GNUNET_SERVER_client_persist_ (struct GNUNET_SERVER_Client *client)
  * GNUNET_SERVER_MessageCallback (or its respective continuations).
  *
  * @param client client we were processing a message of
  * GNUNET_SERVER_MessageCallback (or its respective continuations).
  *
  * @param client client we were processing a message of
- * @param success GNUNET_OK to keep the connection open and
+ * @param success #GNUNET_OK to keep the connection open and
  *                          continue to receive
  *                          continue to receive
- *                GNUNET_NO to close the connection (normal behavior)
- *                GNUNET_SYSERR to close the connection (signal
+ *                #GNUNET_NO to close the connection (normal behavior)
+ *                #GNUNET_SYSERR to close the connection (signal
  *                          serious error)
  */
 void
  *                          serious error)
  */
 void
-GNUNET_SERVER_receive_done (struct GNUNET_SERVER_Client *client, int success)
+GNUNET_SERVER_receive_done (struct GNUNET_SERVER_Client *client,
+                           int success)
 {
   if (NULL == client)
     return;
 {
   if (NULL == client)
     return;
@@ -1531,10 +1737,10 @@ GNUNET_SERVER_receive_done (struct GNUNET_SERVER_Client *client, int success)
          "GNUNET_SERVER_receive_done called, but more clients pending\n");
     return;
   }
          "GNUNET_SERVER_receive_done called, but more clients pending\n");
     return;
   }
-  if (GNUNET_SCHEDULER_NO_TASK != client->warn_task)
+  if (NULL != client->warn_task)
   {
     GNUNET_SCHEDULER_cancel (client->warn_task);
   {
     GNUNET_SCHEDULER_cancel (client->warn_task);
-    client->warn_task = GNUNET_SCHEDULER_NO_TASK;
+    client->warn_task = NULL;
   }
   if (GNUNET_YES == client->in_process_client_buffer)
   {
   }
   if (GNUNET_YES == client->in_process_client_buffer)
   {
@@ -1549,8 +1755,9 @@ GNUNET_SERVER_receive_done (struct GNUNET_SERVER_Client *client, int success)
   }
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "GNUNET_SERVER_receive_done causes restart in reading from the socket\n");
   }
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "GNUNET_SERVER_receive_done causes restart in reading from the socket\n");
-  GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == client->restart_task);
-  client->restart_task = GNUNET_SCHEDULER_add_now (&restart_processing, client);
+  GNUNET_assert (NULL == client->restart_task);
+  client->restart_task = GNUNET_SCHEDULER_add_now (&restart_processing,
+                                                   client);
 }
 
 
 }