fix pointer indentation
[oweals/gnunet.git] / src / testbed / gnunet-service-testbed_peers.c
index c07fa87c5419d2616e0b00cc1a4583f04e4b76f7..d3d597d4f96f2107b5b7c9bd2129066b258b0daa 100644 (file)
@@ -1,28 +1,28 @@
 /*
-  This file is part of GNUnet.
-  (C) 2008--2013 Christian Grothoff (and other contributing authors)
+   This file is part of GNUnet.
+   Copyright (C) 2008--2013, 2016 GNUnet e.V.
 
-  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
-  option) any later version.
+   GNUnet is free software: you can redistribute it and/or modify it
+   under the terms of the GNU Affero General Public License as published
+   by the Free Software Foundation, either version 3 of the License,
+   or (at your option) any later version.
 
-  GNUnet is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  General Public License for more details.
+   GNUnet is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Affero General Public License for more details.
 
-  You should have received a copy of the GNU General Public License
-  along with GNUnet; see the file COPYING.  If not, write to the
-  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-  Boston, MA 02111-1307, USA.
-*/
+   You should have received a copy of the GNU Affero General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+     SPDX-License-Identifier: AGPL3.0-or-later
+ */
 
 
 /**
  * @file testbed/gnunet-service-testbed_peers.c
  * @brief implementation of TESTBED service that deals with peer management
- * @author Sree Harsha Totakura <sreeharsha@totakura.in> 
+ * @author Sree Harsha Totakura <sreeharsha@totakura.in>
  */
 
 #include "gnunet-service-testbed.h"
  */
 struct Peer **GST_peer_list;
 
+/**
+ * The current number of peers running locally under this controller
+ */
+unsigned int GST_num_local_peers;
+
 
 /**
  * Context information to manage peers' services
@@ -64,13 +69,18 @@ struct ManageServiceContext
   /**
    * The client which requested to manage the peer's service
    */
-  struct GNUNET_SERVER_Client *client;
-  
+  struct GNUNET_SERVICE_Client *client;
+
+  /**
+   * Name of the service.
+   */
+  char *service;
+
   /**
    * The operation id of the associated request
    */
   uint64_t op_id;
-  
+
   /**
    * 1 if the service at the peer has to be started; 0 if it has to be stopped
    */
@@ -80,7 +90,7 @@ struct ManageServiceContext
    * Is this context expired?  Do not work on this context if it is set to
    * GNUNET_YES
    */
-  uint8_t expired;  
+  uint8_t expired;
 };
 
 
@@ -102,7 +112,7 @@ struct PeerReconfigureContext
   /**
    * The client which gave this operation to us
    */
-  struct GNUNET_SERVER_Client *client;
+  struct GNUNET_SERVICE_Client *client;
 
   /**
    * The configuration handle to use as the new template
@@ -138,7 +148,6 @@ static struct PeerReconfigureContext *prc_head;
 static struct PeerReconfigureContext *prc_tail;
 
 
-
 /**
  * DLL head for queue of manage service requests
  */
@@ -162,6 +171,8 @@ peer_list_add (struct Peer *peer)
     GST_array_grow_large_enough (GST_peer_list, GST_peer_list_size, peer->id);
   GNUNET_assert (NULL == GST_peer_list[peer->id]);
   GST_peer_list[peer->id] = peer;
+  if (GNUNET_NO == peer->is_remote)
+    GST_num_local_peers++;
 }
 
 
@@ -176,6 +187,8 @@ peer_list_remove (struct Peer *peer)
   unsigned int orig_size;
   uint32_t id;
 
+  if (GNUNET_NO == peer->is_remote)
+    GST_num_local_peers--;
   GST_peer_list[peer->id] = NULL;
   orig_size = GST_peer_list_size;
   while (GST_peer_list_size >= LIST_GROW_STEP)
@@ -192,8 +205,8 @@ peer_list_remove (struct Peer *peer)
   if (orig_size == GST_peer_list_size)
     return;
   GST_peer_list =
-      GNUNET_realloc (GST_peer_list,
-                      sizeof (struct Peer *) * GST_peer_list_size);
+    GNUNET_realloc (GST_peer_list,
+                    sizeof(struct Peer *) * GST_peer_list_size);
 }
 
 
@@ -202,16 +215,14 @@ peer_list_remove (struct Peer *peer)
  * timed out
  *
  * @param cls the FowardedOperationContext
- * @param tc the TaskContext from the scheduler
  */
 static void
-peer_create_forward_timeout (void *cls,
-                             const struct GNUNET_SCHEDULER_TaskContext *tc)
+peer_create_forward_timeout (void *cls)
 {
   struct ForwardedOperationContext *fopc = cls;
 
   GNUNET_free (fopc->cls);
-  GST_forwarded_operation_timeout (fopc, tc);
+  GST_forwarded_operation_timeout (fopc);
 }
 
 
@@ -234,7 +245,8 @@ peer_create_success_cb (void *cls, const struct GNUNET_MessageHeader *msg)
     remote_peer = fopc->cls;
     peer_list_add (remote_peer);
   }
-  GST_forwarded_operation_reply_relay (fopc, msg);
+  GST_forwarded_operation_reply_relay (fopc,
+                                       msg);
 }
 
 
@@ -265,6 +277,115 @@ GST_destroy_peer (struct Peer *peer)
 }
 
 
+/**
+ * Cleanup the context information created for managing a peer's service
+ *
+ * @param mctx the ManageServiceContext
+ */
+static void
+cleanup_mctx (struct ManageServiceContext *mctx)
+{
+  mctx->expired = GNUNET_YES;
+  GNUNET_CONTAINER_DLL_remove (mctx_head,
+                               mctx_tail,
+                               mctx);
+  GNUNET_ARM_disconnect (mctx->ah);
+  GNUNET_assert (0 < mctx->peer->reference_cnt);
+  mctx->peer->reference_cnt--;
+  if ((GNUNET_YES == mctx->peer->destroy_flag) &&
+      (0 == mctx->peer->reference_cnt))
+    GST_destroy_peer (mctx->peer);
+  GNUNET_free (mctx->service);
+  GNUNET_free (mctx);
+}
+
+
+/**
+ * Stops a peer
+ *
+ * @param peer the peer to stop
+ * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
+ */
+static int
+stop_peer (struct Peer *peer)
+{
+  GNUNET_assert (GNUNET_NO == peer->is_remote);
+  if (GNUNET_OK != GNUNET_TESTING_peer_kill (peer->details.local.peer))
+    return GNUNET_SYSERR;
+  peer->details.local.is_running = GNUNET_NO;
+  return GNUNET_OK;
+}
+
+
+/**
+ * Cleans up the given PeerReconfigureContext
+ *
+ * @param prc the PeerReconfigureContext
+ */
+static void
+cleanup_prc (struct PeerReconfigureContext *prc)
+{
+  struct Peer *peer;
+
+  if (VALID_PEER_ID (prc->peer_id))
+  {
+    peer = GST_peer_list [prc->peer_id];
+    if (1 != prc->stopped)
+    {
+      GNUNET_TESTING_peer_stop_async_cancel (peer->details.local.peer);
+      stop_peer (peer);         /* Stop the peer synchronously */
+    }
+  }
+  if (NULL != prc->cfg)
+    GNUNET_CONFIGURATION_destroy (prc->cfg);
+  GNUNET_CONTAINER_DLL_remove (prc_head,
+                               prc_tail,
+                               prc);
+  GNUNET_free (prc);
+}
+
+
+/**
+ * Notify peers subsystem that @a client disconnected.
+ *
+ * @param client the client that disconnected
+ */
+void
+GST_notify_client_disconnect_peers (struct GNUNET_SERVICE_Client *client)
+{
+  struct ForwardedOperationContext *fopc;
+  struct ForwardedOperationContext *fopcn;
+  struct ManageServiceContext *mctx;
+  struct ManageServiceContext *mctxn;
+  struct PeerReconfigureContext *prc;
+  struct PeerReconfigureContext *prcn;
+
+  for (fopc = fopcq_head; NULL != fopc; fopc = fopcn)
+  {
+    fopcn = fopc->next;
+    if (client == fopc->client)
+    {
+      if (OP_PEER_CREATE == fopc->type)
+        GNUNET_free (fopc->cls);
+      GNUNET_SCHEDULER_cancel (fopc->timeout_task);
+      GST_forwarded_operation_timeout (fopc);
+    }
+  }
+  for (mctx = mctx_head; NULL != mctx; mctx = mctxn)
+  {
+    mctxn = mctx->next;
+    if (client == mctx->client)
+      cleanup_mctx (mctx);
+  }
+  for (prc = prc_head; NULL != prc; prc = prcn)
+  {
+    prcn = prc->next;
+    if (client == prc->client)
+      cleanup_prc (prc);
+  }
+}
+
+
 /**
  * Callback to be called when forwarded peer destroy operation is successfull. We
  * have to relay the reply msg back to the client
@@ -287,22 +408,38 @@ peer_destroy_success_cb (void *cls, const struct GNUNET_MessageHeader *msg)
     if (0 == remote_peer->reference_cnt)
       GST_destroy_peer (remote_peer);
   }
-  GST_forwarded_operation_reply_relay (fopc, msg);
+  GST_forwarded_operation_reply_relay (fopc,
+                                       msg);
 }
 
 
 /**
- * Handler for GNUNET_MESSAGE_TYPE_TESTBED_CREATEPEER messages
+ * Check #GNUNET_MESSAGE_TYPE_TESTBED_CREATEPEER messages
  *
- * @param cls NULL
- * @param client identification of the client
- * @param message the actual message
+ * @param cls identification of the client
+ * @param msg the actual message
+ * @return #GNUNET_OK if @a msg is well-formed
+ */
+int
+check_peer_create (void *cls,
+                   const struct GNUNET_TESTBED_PeerCreateMessage *msg)
+{
+  return GNUNET_OK; /* checked later */
+}
+
+
+/**
+ * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_CREATEPEER messages
+ *
+ * @param cls identification of the client
+ * @param msg the actual message
  */
 void
-GST_handle_peer_create (void *cls, struct GNUNET_SERVER_Client *client,
-                        const struct GNUNET_MessageHeader *message)
+handle_peer_create (void *cls,
+                    const struct GNUNET_TESTBED_PeerCreateMessage *msg)
 {
-  const struct GNUNET_TESTBED_PeerCreateMessage *msg;
+  struct GNUNET_SERVICE_Client *client = cls;
+  struct GNUNET_MQ_Envelope *env;
   struct GNUNET_TESTBED_PeerCreateSuccessEventMessage *reply;
   struct GNUNET_CONFIGURATION_Handle *cfg;
   struct ForwardedOperationContext *fo_ctxt;
@@ -311,79 +448,79 @@ GST_handle_peer_create (void *cls, struct GNUNET_SERVER_Client *client,
   char *emsg;
   uint32_t host_id;
   uint32_t peer_id;
-  uint16_t msize;
 
-
-  msize = ntohs (message->size);
-  if (msize <= sizeof (struct GNUNET_TESTBED_PeerCreateMessage))
-  {
-    GNUNET_break (0);           /* We need configuration */
-    GNUNET_SERVER_receive_done (client, GNUNET_OK);
-    return;
-  }
-  msg = (const struct GNUNET_TESTBED_PeerCreateMessage *) message;
   host_id = ntohl (msg->host_id);
   peer_id = ntohl (msg->peer_id);
   if (VALID_PEER_ID (peer_id))
   {
-    (void) GNUNET_asprintf (&emsg, "Peer with ID %u already exists", peer_id);
-    GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id),
+    (void) GNUNET_asprintf (&emsg,
+                            "Peer with ID %u already exists",
+                            peer_id);
+    GST_send_operation_fail_msg (client,
+                                 GNUNET_ntohll (msg->operation_id),
                                  emsg);
     GNUNET_free (emsg);
-    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    GNUNET_SERVICE_client_continue (client);
     return;
   }
   if (UINT32_MAX == peer_id)
-  {    
-    GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id),
+  {
+    GST_send_operation_fail_msg (client,
+                                 GNUNET_ntohll (msg->operation_id),
                                  "Cannot create peer with given ID");
-    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    GNUNET_SERVICE_client_continue (client);
     return;
   }
   if (host_id == GST_context->host_id)
   {
     /* We are responsible for this peer */
-    cfg = GNUNET_TESTBED_extract_config_ (message);
+    cfg = GNUNET_TESTBED_extract_config_ (&msg->header);
     if (NULL == cfg)
     {
       GNUNET_break (0);
-      GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+      GNUNET_SERVICE_client_drop (client);
       return;
     }
-    GNUNET_CONFIGURATION_set_value_number (cfg, "TESTBED", "PEERID",
+    GNUNET_CONFIGURATION_set_value_number (cfg,
+                                           "TESTBED",
+                                           "PEERID",
+                                           (unsigned long long) peer_id);
+
+    GNUNET_CONFIGURATION_set_value_number (cfg,
+                                           "PATHS",
+                                           "PEERID",
                                            (unsigned long long) peer_id);
-    peer = GNUNET_malloc (sizeof (struct Peer));
+    peer = GNUNET_new (struct Peer);
     peer->is_remote = GNUNET_NO;
     peer->details.local.cfg = cfg;
     peer->id = peer_id;
-    LOG_DEBUG ("Creating peer with id: %u\n", (unsigned int) peer->id);
+    LOG_DEBUG ("Creating peer with id: %u\n",
+               (unsigned int) peer->id);
     peer->details.local.peer =
-        GNUNET_TESTING_peer_configure (GST_context->system,
-                                       peer->details.local.cfg, peer->id,
-                                       NULL /* Peer id */ ,
-                                       &emsg);
+      GNUNET_TESTING_peer_configure (GST_context->system,
+                                     peer->details.local.cfg, peer->id,
+                                     NULL /* Peer id */,
+                                     &emsg);
     if (NULL == peer->details.local.peer)
     {
-      LOG (GNUNET_ERROR_TYPE_WARNING, "Configuring peer failed: %s\n", emsg);
+      LOG (GNUNET_ERROR_TYPE_WARNING,
+           "Configuring peer failed: %s\n",
+           emsg);
       GNUNET_free (emsg);
       GNUNET_free (peer);
       GNUNET_break (0);
-      GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+      GNUNET_SERVICE_client_drop (client);
       return;
     }
     peer->details.local.is_running = GNUNET_NO;
     peer_list_add (peer);
-    reply =
-        GNUNET_malloc (sizeof
-                       (struct GNUNET_TESTBED_PeerCreateSuccessEventMessage));
-    reply->header.size =
-        htons (sizeof (struct GNUNET_TESTBED_PeerCreateSuccessEventMessage));
-    reply->header.type =
-        htons (GNUNET_MESSAGE_TYPE_TESTBED_CREATE_PEER_SUCCESS);
+    env = GNUNET_MQ_msg (reply,
+                         GNUNET_MESSAGE_TYPE_TESTBED_CREATE_PEER_SUCCESS);
     reply->peer_id = msg->peer_id;
     reply->operation_id = msg->operation_id;
-    GST_queue_message (client, &reply->header);
-    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
+                    env);
+    GNUNET_SERVICE_client_continue (client);
     return;
   }
 
@@ -392,83 +529,90 @@ GST_handle_peer_create (void *cls, struct GNUNET_SERVER_Client *client,
   if (NULL == route)
   {
     GNUNET_break (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    GNUNET_SERVICE_client_continue (client);  // ?
     return;
   }
-  peer = GNUNET_malloc (sizeof (struct Peer));
+  peer = GNUNET_new (struct Peer);
   peer->is_remote = GNUNET_YES;
   peer->id = peer_id;
   peer->details.remote.slave = GST_slave_list[route->dest];
   peer->details.remote.remote_host_id = host_id;
-  fo_ctxt = GNUNET_malloc (sizeof (struct ForwardedOperationContext));
-  GNUNET_SERVER_client_keep (client);
+  fo_ctxt = GNUNET_new (struct ForwardedOperationContext);
   fo_ctxt->client = client;
   fo_ctxt->operation_id = GNUNET_ntohll (msg->operation_id);
   fo_ctxt->cls = peer;
   fo_ctxt->type = OP_PEER_CREATE;
   fo_ctxt->opc =
-      GNUNET_TESTBED_forward_operation_msg_ (GST_slave_list
-                                             [route->dest]->controller,
-                                             fo_ctxt->operation_id,
-                                             &msg->header,
-                                             peer_create_success_cb, fo_ctxt);
+    GNUNET_TESTBED_forward_operation_msg_ (GST_slave_list
+                                           [route->dest]->controller,
+                                           fo_ctxt->operation_id,
+                                           &msg->header,
+                                           &peer_create_success_cb,
+                                           fo_ctxt);
   fo_ctxt->timeout_task =
-      GNUNET_SCHEDULER_add_delayed (GST_timeout, &peer_create_forward_timeout,
+    GNUNET_SCHEDULER_add_delayed (GST_timeout,
+                                  &peer_create_forward_timeout,
+                                  fo_ctxt);
+  GNUNET_CONTAINER_DLL_insert_tail (fopcq_head,
+                                    fopcq_tail,
                                     fo_ctxt);
-  GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fo_ctxt);
-  GNUNET_SERVER_receive_done (client, GNUNET_OK);
+  GNUNET_SERVICE_client_continue (client);
 }
 
 
 /**
- * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_DESTROYPEER messages
+ * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_DESTROYPEER messages
  *
- * @param cls NULL
- * @param client identification of the client
- * @param message the actual message
+ * @param cls identification of the client
+ * @param msg the actual message
  */
 void
-GST_handle_peer_destroy (void *cls, struct GNUNET_SERVER_Client *client,
-                         const struct GNUNET_MessageHeader *message)
+handle_peer_destroy (void *cls,
+                     const struct GNUNET_TESTBED_PeerDestroyMessage *msg)
 {
-  const struct GNUNET_TESTBED_PeerDestroyMessage *msg;
+  struct GNUNET_SERVICE_Client *client = cls;
   struct ForwardedOperationContext *fopc;
   struct Peer *peer;
   uint32_t peer_id;
 
-  msg = (const struct GNUNET_TESTBED_PeerDestroyMessage *) message;
   peer_id = ntohl (msg->peer_id);
-  LOG_DEBUG ("Received peer destory on peer: %u and operation id: %ul\n",
-             peer_id, GNUNET_ntohll (msg->operation_id));
-  if (!VALID_PEER_ID (peer_id))
+  LOG_DEBUG ("Received peer destory on peer: %u and operation id: %llu\n",
+             (unsigned int) peer_id,
+             (unsigned long long) GNUNET_ntohll (msg->operation_id));
+  if (! VALID_PEER_ID (peer_id))
   {
     LOG (GNUNET_ERROR_TYPE_ERROR,
          "Asked to destroy a non existent peer with id: %u\n", peer_id);
-    GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id),
+    GST_send_operation_fail_msg (client,
+                                 GNUNET_ntohll (msg->operation_id),
                                  "Peer doesn't exist");
-    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    GNUNET_SERVICE_client_continue (client);
     return;
   }
   peer = GST_peer_list[peer_id];
   if (GNUNET_YES == peer->is_remote)
   {
     /* Forward the destory message to sub controller */
-    fopc = GNUNET_malloc (sizeof (struct ForwardedOperationContext));
-    GNUNET_SERVER_client_keep (client);
+    fopc = GNUNET_new (struct ForwardedOperationContext);
     fopc->client = client;
     fopc->cls = peer;
     fopc->type = OP_PEER_DESTROY;
     fopc->operation_id = GNUNET_ntohll (msg->operation_id);
     fopc->opc =
-        GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote.
-                                               slave->controller,
-                                               fopc->operation_id, &msg->header,
-                                               &peer_destroy_success_cb, fopc);
+      GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote.
+                                             slave->controller,
+                                             fopc->operation_id,
+                                             &msg->header,
+                                             &peer_destroy_success_cb,
+                                             fopc);
     fopc->timeout_task =
-        GNUNET_SCHEDULER_add_delayed (GST_timeout, &GST_forwarded_operation_timeout,
+      GNUNET_SCHEDULER_add_delayed (GST_timeout,
+                                    &GST_forwarded_operation_timeout,
+                                    fopc);
+    GNUNET_CONTAINER_DLL_insert_tail (fopcq_head,
+                                      fopcq_tail,
                                       fopc);
-    GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc);
-    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    GNUNET_SERVICE_client_continue (client);
     return;
   }
   peer->destroy_flag = GNUNET_YES;
@@ -477,8 +621,9 @@ GST_handle_peer_destroy (void *cls, struct GNUNET_SERVER_Client *client,
   else
     LOG (GNUNET_ERROR_TYPE_DEBUG,
          "Delaying peer destroy as peer is currently in use\n");
-  GST_send_operation_success_msg (client, GNUNET_ntohll (msg->operation_id));
-  GNUNET_SERVER_receive_done (client, GNUNET_OK);
+  GST_send_operation_success_msg (client,
+                                  GNUNET_ntohll (msg->operation_id));
+  GNUNET_SERVICE_client_continue (client);
 }
 
 
@@ -486,7 +631,7 @@ GST_handle_peer_destroy (void *cls, struct GNUNET_SERVER_Client *client,
  * Stats a peer
  *
  * @param peer the peer to start
- * @return GNUNET_OK upon success; GNUNET_SYSERR upon failure
+ * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
  */
 static int
 start_peer (struct Peer *peer)
@@ -500,173 +645,172 @@ start_peer (struct Peer *peer)
 
 
 /**
- * Stops a peer
+ * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_START_PEER messages
  *
- * @param peer the peer to stop
- * @return GNUNET_OK upon success; GNUNET_SYSERR upon failure
- */
-static int
-stop_peer (struct Peer *peer)
-{
-  GNUNET_assert (GNUNET_NO == peer->is_remote);
-  if (GNUNET_OK != GNUNET_TESTING_peer_kill (peer->details.local.peer))
-    return GNUNET_SYSERR;
-  peer->details.local.is_running = GNUNET_NO;
-  return GNUNET_OK;
-}
-
-
-/**
- * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_DESTROYPEER messages
- *
- * @param cls NULL
- * @param client identification of the client
- * @param message the actual message
+ * @param cls identification of the client
+ * @param msg the actual message
  */
 void
-GST_handle_peer_start (void *cls, struct GNUNET_SERVER_Client *client,
-                       const struct GNUNET_MessageHeader *message)
+handle_peer_start (void *cls,
+                   const struct GNUNET_TESTBED_PeerStartMessage *msg)
 {
-  const struct GNUNET_TESTBED_PeerStartMessage *msg;
+  struct GNUNET_SERVICE_Client *client = cls;
+  struct GNUNET_MQ_Envelope *env;
   struct GNUNET_TESTBED_PeerEventMessage *reply;
   struct ForwardedOperationContext *fopc;
   struct Peer *peer;
   uint32_t peer_id;
 
-  msg = (const struct GNUNET_TESTBED_PeerStartMessage *) message;
   peer_id = ntohl (msg->peer_id);
-  if (!VALID_PEER_ID (peer_id))
+  if (! VALID_PEER_ID (peer_id))
   {
     GNUNET_break (0);
     LOG (GNUNET_ERROR_TYPE_ERROR,
-         "Asked to start a non existent peer with id: %u\n", peer_id);
-    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+         "Asked to start a non existent peer with id: %u\n",
+         peer_id);
+    GNUNET_SERVICE_client_continue (client);
     return;
   }
   peer = GST_peer_list[peer_id];
   if (GNUNET_YES == peer->is_remote)
   {
-    fopc = GNUNET_malloc (sizeof (struct ForwardedOperationContext));
-    GNUNET_SERVER_client_keep (client);
+    fopc = GNUNET_new (struct ForwardedOperationContext);
     fopc->client = client;
     fopc->operation_id = GNUNET_ntohll (msg->operation_id);
     fopc->type = OP_PEER_START;
     fopc->opc =
-        GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote.
-                                               slave->controller,
-                                               fopc->operation_id, &msg->header,
-                                               &GST_forwarded_operation_reply_relay,
-                                               fopc);
+      GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote.
+                                             slave->controller,
+                                             fopc->operation_id, &msg->header,
+                                             &
+                                             GST_forwarded_operation_reply_relay,
+                                             fopc);
     fopc->timeout_task =
-        GNUNET_SCHEDULER_add_delayed (GST_timeout, &GST_forwarded_operation_timeout,
+      GNUNET_SCHEDULER_add_delayed (GST_timeout,
+                                    &GST_forwarded_operation_timeout,
+                                    fopc);
+    GNUNET_CONTAINER_DLL_insert_tail (fopcq_head,
+                                      fopcq_tail,
                                       fopc);
-    GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc);
-    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    GNUNET_SERVICE_client_continue (client);
     return;
   }
   if (GNUNET_OK != start_peer (peer))
   {
     GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id),
                                  "Failed to start");
-    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    GNUNET_SERVICE_client_continue (client);
     return;
   }
-  reply = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_PeerEventMessage));
-  reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_PEER_EVENT);
-  reply->header.size = htons (sizeof (struct GNUNET_TESTBED_PeerEventMessage));
+  env = GNUNET_MQ_msg (reply,
+                       GNUNET_MESSAGE_TYPE_TESTBED_PEER_EVENT);
   reply->event_type = htonl (GNUNET_TESTBED_ET_PEER_START);
   reply->host_id = htonl (GST_context->host_id);
   reply->peer_id = msg->peer_id;
   reply->operation_id = msg->operation_id;
-  GST_queue_message (client, &reply->header);
-  GNUNET_SERVER_receive_done (client, GNUNET_OK);
+  GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
+                  env);
+  GNUNET_SERVICE_client_continue (client);
 }
 
 
 /**
- * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_DESTROYPEER messages
+ * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_STOP_PEER messages
  *
- * @param cls NULL
- * @param client identification of the client
- * @param message the actual message
+ * @param cls identification of the client
+ * @param msg the actual message
  */
 void
-GST_handle_peer_stop (void *cls, struct GNUNET_SERVER_Client *client,
-                      const struct GNUNET_MessageHeader *message)
+handle_peer_stop (void *cls,
+                  const struct GNUNET_TESTBED_PeerStopMessage *msg)
 {
-  const struct GNUNET_TESTBED_PeerStopMessage *msg;
+  struct GNUNET_SERVICE_Client *client = cls;
+  struct GNUNET_MQ_Envelope *env;
   struct GNUNET_TESTBED_PeerEventMessage *reply;
   struct ForwardedOperationContext *fopc;
   struct Peer *peer;
   uint32_t peer_id;
 
-  msg = (const struct GNUNET_TESTBED_PeerStopMessage *) message;
   peer_id = ntohl (msg->peer_id);
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "Received PEER_STOP for peer %u\n", peer_id);
-  if (!VALID_PEER_ID (peer_id))
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Received PEER_STOP for peer %u\n",
+       (unsigned int) peer_id);
+  if (! VALID_PEER_ID (peer_id))
   {
-    GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id),
+    GST_send_operation_fail_msg (client,
+                                 GNUNET_ntohll (msg->operation_id),
                                  "Peer not found");
-    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    GNUNET_SERVICE_client_continue (client);
     return;
   }
   peer = GST_peer_list[peer_id];
   if (GNUNET_YES == peer->is_remote)
   {
-    LOG (GNUNET_ERROR_TYPE_DEBUG, "Forwarding PEER_STOP for peer %u\n",
-         peer_id);
-    fopc = GNUNET_malloc (sizeof (struct ForwardedOperationContext));
-    GNUNET_SERVER_client_keep (client);
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Forwarding PEER_STOP for peer %u\n",
+         (unsigned int) peer_id);
+    fopc = GNUNET_new (struct ForwardedOperationContext);
     fopc->client = client;
     fopc->operation_id = GNUNET_ntohll (msg->operation_id);
     fopc->type = OP_PEER_STOP;
     fopc->opc =
-        GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote.
-                                               slave->controller,
-                                               fopc->operation_id, &msg->header,
-                                               &GST_forwarded_operation_reply_relay,
-                                               fopc);
+      GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote.
+                                             slave->controller,
+                                             fopc->operation_id,
+                                             &msg->header,
+                                             &
+                                             GST_forwarded_operation_reply_relay,
+                                             fopc);
     fopc->timeout_task =
-        GNUNET_SCHEDULER_add_delayed (GST_timeout, &GST_forwarded_operation_timeout,
+      GNUNET_SCHEDULER_add_delayed (GST_timeout,
+                                    &GST_forwarded_operation_timeout,
+                                    fopc);
+    GNUNET_CONTAINER_DLL_insert_tail (fopcq_head,
+                                      fopcq_tail,
                                       fopc);
-    GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc);
-    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    GNUNET_SERVICE_client_continue (client);
     return;
   }
   if (GNUNET_OK != stop_peer (peer))
   {
-    LOG (GNUNET_ERROR_TYPE_WARNING, "Stopping peer %u failed\n", peer_id);
-    GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id),
+    LOG (GNUNET_ERROR_TYPE_WARNING,
+         "Stopping peer %u failed\n",
+         (unsigned int) peer_id);
+    GST_send_operation_fail_msg (client,
+                                 GNUNET_ntohll (msg->operation_id),
                                  "Peer not running");
-    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    GNUNET_SERVICE_client_continue (client);
     return;
   }
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "Peer %u successfully stopped\n", peer_id);
-  reply = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_PeerEventMessage));
-  reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_PEER_EVENT);
-  reply->header.size = htons (sizeof (struct GNUNET_TESTBED_PeerEventMessage));
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Peer %u successfully stopped\n",
+       (unsigned int) peer_id);
+  env = GNUNET_MQ_msg (reply,
+                       GNUNET_MESSAGE_TYPE_TESTBED_PEER_EVENT);
   reply->event_type = htonl (GNUNET_TESTBED_ET_PEER_STOP);
   reply->host_id = htonl (GST_context->host_id);
   reply->peer_id = msg->peer_id;
   reply->operation_id = msg->operation_id;
-  GST_queue_message (client, &reply->header);
-  GNUNET_SERVER_receive_done (client, GNUNET_OK);
+  GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
+                  env);
+  GNUNET_SERVICE_client_continue (client);
   GNUNET_TESTING_peer_wait (peer->details.local.peer);
 }
 
 
 /**
- * Handler for GNUNET_MESSAGE_TYPE_TESTBED_GETPEERCONFIG messages
+ * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_GET_PEER_INFORMATION messages
  *
- * @param cls NULL
- * @param client identification of the client
- * @param message the actual message
+ * @param cls identification of the client
+ * @param msg the actual message
  */
 void
-GST_handle_peer_get_config (void *cls, struct GNUNET_SERVER_Client *client,
-                            const struct GNUNET_MessageHeader *message)
+handle_peer_get_config (void *cls,
+                        const struct
+                        GNUNET_TESTBED_PeerGetConfigurationMessage *msg)
 {
-  const struct GNUNET_TESTBED_PeerGetConfigurationMessage *msg;
+  struct GNUNET_SERVICE_Client *client = cls;
+  struct GNUNET_MQ_Envelope *env;
   struct GNUNET_TESTBED_PeerConfigurationInformationMessage *reply;
   struct ForwardedOperationContext *fopc;
   struct Peer *peer;
@@ -675,98 +819,107 @@ GST_handle_peer_get_config (void *cls, struct GNUNET_SERVER_Client *client,
   size_t c_size;
   size_t xc_size;
   uint32_t peer_id;
-  uint16_t msize;
 
-  msg = (const struct GNUNET_TESTBED_PeerGetConfigurationMessage *) message;
   peer_id = ntohl (msg->peer_id);
-  LOG_DEBUG ("Received GET_CONFIG for peer %u\n", peer_id);
-  if (!VALID_PEER_ID (peer_id))
+  LOG_DEBUG ("Received GET_CONFIG for peer %u\n",
+             (unsigned int) peer_id);
+  if (! VALID_PEER_ID (peer_id))
   {
-    GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id),
+    GST_send_operation_fail_msg (client,
+                                 GNUNET_ntohll (msg->operation_id),
                                  "Peer not found");
-    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    GNUNET_SERVICE_client_continue (client);
     return;
   }
   peer = GST_peer_list[peer_id];
   if (GNUNET_YES == peer->is_remote)
   {
-    LOG_DEBUG ("Forwarding PEER_GET_CONFIG for peer: %u\n", peer_id);
-    fopc = GNUNET_malloc (sizeof (struct ForwardedOperationContext));
-    GNUNET_SERVER_client_keep (client);
+    LOG_DEBUG ("Forwarding PEER_GET_CONFIG for peer: %u\n",
+               (unsigned int) peer_id);
+    fopc = GNUNET_new (struct ForwardedOperationContext);
     fopc->client = client;
     fopc->operation_id = GNUNET_ntohll (msg->operation_id);
     fopc->type = OP_PEER_INFO;
     fopc->opc =
-        GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote.
-                                               slave->controller,
-                                               fopc->operation_id, &msg->header,
-                                               &GST_forwarded_operation_reply_relay,
-                                               fopc);
+      GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote.
+                                             slave->controller,
+                                             fopc->operation_id,
+                                             &msg->header,
+                                             &
+                                             GST_forwarded_operation_reply_relay,
+                                             fopc);
     fopc->timeout_task =
-        GNUNET_SCHEDULER_add_delayed (GST_timeout, &GST_forwarded_operation_timeout,
+      GNUNET_SCHEDULER_add_delayed (GST_timeout,
+                                    &GST_forwarded_operation_timeout,
+                                    fopc);
+    GNUNET_CONTAINER_DLL_insert_tail (fopcq_head,
+                                      fopcq_tail,
                                       fopc);
-    GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc);
-    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    GNUNET_SERVICE_client_continue (client);
     return;
   }
-  LOG_DEBUG ("Received PEER_GET_CONFIG for peer: %u\n", peer_id);
+  LOG_DEBUG ("Received PEER_GET_CONFIG for peer: %u\n",
+             peer_id);
   config =
-      GNUNET_CONFIGURATION_serialize (GST_peer_list[peer_id]->details.local.cfg,
-                                      &c_size);
-  xc_size = GNUNET_TESTBED_compress_config_ (config, c_size, &xconfig);
+    GNUNET_CONFIGURATION_serialize (GST_peer_list[peer_id]->details.local.cfg,
+                                    &c_size);
+  xc_size = GNUNET_TESTBED_compress_config_ (config,
+                                             c_size,
+                                             &xconfig);
   GNUNET_free (config);
-  msize =
-      xc_size +
-      sizeof (struct GNUNET_TESTBED_PeerConfigurationInformationMessage);
-  reply = GNUNET_realloc (xconfig, msize);
-  (void) memmove (&reply[1], reply, xc_size);
-  reply->header.size = htons (msize);
-  reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_PEER_CONFIGURATION);
+  env = GNUNET_MQ_msg_extra (reply,
+                             xc_size,
+                             GNUNET_MESSAGE_TYPE_TESTBED_PEER_INFORMATION);
   reply->peer_id = msg->peer_id;
   reply->operation_id = msg->operation_id;
   GNUNET_TESTING_peer_get_identity (GST_peer_list[peer_id]->details.local.peer,
                                     &reply->peer_identity);
   reply->config_size = htons ((uint16_t) c_size);
-  GST_queue_message (client, &reply->header);
-  GNUNET_SERVER_receive_done (client, GNUNET_OK);
+  GNUNET_memcpy (&reply[1],
+                 xconfig,
+                 xc_size);
+  GNUNET_free (xconfig);
+  GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
+                  env);
+  GNUNET_SERVICE_client_continue (client);
 }
 
 
 /**
- * Cleans up the given PeerReconfigureContext
- *
- * @param prc the PeerReconfigureContext
+ * Cleans up the Peer reconfigure context list
  */
-static void
-cleanup_prc (struct PeerReconfigureContext *prc)
+void
+GST_free_prcq ()
 {
-  struct Peer *peer;
-
-  if (VALID_PEER_ID (prc->peer_id))
-  {
-    peer = GST_peer_list [prc->peer_id];
-    if (1 != prc->stopped)
-    {
-      GNUNET_TESTING_peer_stop_async_cancel (peer->details.local.peer);
-      stop_peer (peer);         /* Stop the peer synchronously */
-    }
-  }
-  if (NULL != prc->cfg)
-    GNUNET_CONFIGURATION_destroy (prc->cfg);
-  GNUNET_SERVER_client_drop (prc->client);
-  GNUNET_CONTAINER_DLL_remove (prc_head, prc_tail, prc);
-  GNUNET_free (prc);
+  while (NULL != prc_head)
+    cleanup_prc (prc_head);
 }
 
 
 /**
- * Cleans up the Peer reconfigure context list
+ * Update peer configuration
+ *
+ * @param peer the peer to update
+ * @param cfg the new configuration
+ * @return error message (freshly allocated); NULL upon success
  */
-void
-GST_free_prcq ()
+static char *
+update_peer_config (struct Peer *peer,
+                    struct GNUNET_CONFIGURATION_Handle *cfg)
 {
-  while (NULL != prc_head)
-    cleanup_prc (prc_head);
+  char *emsg;
+
+  GNUNET_TESTING_peer_destroy (peer->details.local.peer);
+  GNUNET_CONFIGURATION_destroy (peer->details.local.cfg);
+  peer->details.local.cfg = cfg;
+  emsg = NULL;
+  peer->details.local.peer
+    = GNUNET_TESTING_peer_configure (GST_context->system,
+                                     peer->details.local.cfg,
+                                     peer->id,
+                                     NULL /* Peer id */,
+                                     &emsg);
+  return emsg;
 }
 
 
@@ -775,164 +928,193 @@ GST_free_prcq ()
  *
  * @param cls the closure given to GNUNET_TESTING_peer_stop_async()
  * @param p the respective peer whose status is being reported
- * @param success GNUNET_YES if the peer is stopped; GNUNET_SYSERR upon any
+ * @param success #GNUNET_YES if the peer is stopped; #GNUNET_SYSERR upon any
  *          error
  */
 static void
-prc_stop_cb (void *cls, struct GNUNET_TESTING_Peer *p, int success)
+prc_stop_cb (void *cls,
+             struct GNUNET_TESTING_Peer *p,
+             int success)
 {
   struct PeerReconfigureContext *prc = cls;
   struct Peer *peer;
   char *emsg;
-  
+
   GNUNET_assert (VALID_PEER_ID (prc->peer_id));
   peer = GST_peer_list [prc->peer_id];
   GNUNET_assert (GNUNET_NO == peer->is_remote);
-  GNUNET_TESTING_peer_destroy (peer->details.local.peer);
-  GNUNET_CONFIGURATION_destroy (peer->details.local.cfg);
-  peer->details.local.cfg = prc->cfg;
+  emsg = update_peer_config (peer, prc->cfg);
   prc->cfg = NULL;
   prc->stopped = 1;
-  emsg = NULL;
-  peer->details.local.peer
-      = GNUNET_TESTING_peer_configure (GST_context->system,
-                                       peer->details.local.cfg, peer->id,
-                                       NULL /* Peer id */ ,
-                                       &emsg);
-  if (NULL == peer->details.local.peer)
+  if (NULL != emsg)
   {
-    GST_send_operation_fail_msg (prc->client, prc->op_id, emsg);
+    GST_send_operation_fail_msg (prc->client,
+                                 prc->op_id,
+                                 emsg);
     goto cleanup;
   }
   if (GNUNET_OK != start_peer (peer))
   {
-    
-    GST_send_operation_fail_msg (prc->client, prc->op_id,
+    GST_send_operation_fail_msg (prc->client,
+                                 prc->op_id,
                                  "Failed to start reconfigured peer");
     goto cleanup;
   }
-  GST_send_operation_success_msg (prc->client, prc->op_id);
-  
- cleanup:
+  GST_send_operation_success_msg (prc->client,
+                                  prc->op_id);
+
+cleanup:
   cleanup_prc (prc);
   return;
 }
 
 
 /**
- * Handler for GNUNET_MESSAGE_TYPDE_TESTBED_RECONFIGURE_PEER type messages.
+ * Check #GNUNET_MESSAGE_TYPDE_TESTBED_RECONFIGURE_PEER type messages.
+ *
+ * @param cls identification of the client
+ * @param msg the actual message
+ * @return #GNUNET_OK if @a msg is well-formed
+ */
+int
+check_peer_reconfigure (void *cls,
+                        const struct GNUNET_TESTBED_PeerReconfigureMessage *msg)
+{
+  return GNUNET_OK; /* checked later */
+}
+
+
+/**
+ * Handler for #GNUNET_MESSAGE_TYPDE_TESTBED_RECONFIGURE_PEER type messages.
  * Should stop the peer asyncronously, destroy it and create it again with the
  * new configuration.
  *
- * @param cls NULL
- * @param client identification of the client
- * @param message the actual message
+ * @param cls identification of the client
+ * @param msg the actual message
  */
 void
-GST_handle_peer_reconfigure (void *cls, struct GNUNET_SERVER_Client *client,
-                             const struct GNUNET_MessageHeader *message)
+handle_peer_reconfigure (void *cls,
+                         const struct
+                         GNUNET_TESTBED_PeerReconfigureMessage *msg)
 {
-  const struct GNUNET_TESTBED_PeerReconfigureMessage *msg;
+  struct GNUNET_SERVICE_Client *client = cls;
   struct Peer *peer;
   struct GNUNET_CONFIGURATION_Handle *cfg;
   struct ForwardedOperationContext *fopc;
   struct PeerReconfigureContext *prc;
+  char *emsg;
   uint64_t op_id;
   uint32_t peer_id;
-  uint16_t msize;
-  
-  msize = ntohs (message->size);
-  if (msize <= sizeof (struct GNUNET_TESTBED_PeerReconfigureMessage))
-  {
-    GNUNET_break_op (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
-    return;
-  }
-  msg = (const struct GNUNET_TESTBED_PeerReconfigureMessage *) message;
+
   peer_id = ntohl (msg->peer_id);
   op_id = GNUNET_ntohll (msg->operation_id);
-  if (!VALID_PEER_ID (peer_id))
+  if (! VALID_PEER_ID (peer_id))
   {
     GNUNET_break (0);
-    GST_send_operation_fail_msg (client, op_id, "Peer not found");
-    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    GST_send_operation_fail_msg (client,
+                                 op_id,
+                                 "Peer not found");
+    GNUNET_SERVICE_client_continue (client);
     return;
   }
   peer = GST_peer_list[peer_id];
   if (GNUNET_YES == peer->is_remote)
   {
     LOG_DEBUG ("Forwarding PEER_RECONFIGURE for peer: %u\n", peer_id);
-    fopc = GNUNET_malloc (sizeof (struct ForwardedOperationContext));
-    GNUNET_SERVER_client_keep (client);
+    fopc = GNUNET_new (struct ForwardedOperationContext);
     fopc->client = client;
     fopc->operation_id = op_id;
     fopc->type = OP_PEER_RECONFIGURE;
     fopc->opc =
-        GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote.
-                                               slave->controller,
-                                               fopc->operation_id, &msg->header,
-                                               &GST_forwarded_operation_reply_relay,
-                                               fopc);
+      GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote.
+                                             slave->controller,
+                                             fopc->operation_id,
+                                             &msg->header,
+                                             &
+                                             GST_forwarded_operation_reply_relay,
+                                             fopc);
     fopc->timeout_task =
-        GNUNET_SCHEDULER_add_delayed (GST_timeout, &GST_forwarded_operation_timeout,
+      GNUNET_SCHEDULER_add_delayed (GST_timeout,
+                                    &GST_forwarded_operation_timeout,
+                                    fopc);
+    GNUNET_CONTAINER_DLL_insert_tail (fopcq_head,
+                                      fopcq_tail,
                                       fopc);
-    GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc);
-    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    GNUNET_SERVICE_client_continue (client);
     return;
   }
-  LOG_DEBUG ("Received PEER_RECONFIGURE for peer %u\n", peer_id);
+  LOG_DEBUG ("Received PEER_RECONFIGURE for peer %u\n",
+             (unsigned int) peer_id);
   if (0 < peer->reference_cnt)
   {
     GNUNET_break (0);
-    GST_send_operation_fail_msg (client, op_id, "Peer in use");
-    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    GST_send_operation_fail_msg (client,
+                                 op_id,
+                                 "Peer in use");
+    GNUNET_SERVICE_client_continue (client);
     return;
   }
   if (GNUNET_YES == peer->destroy_flag)
   {
     GNUNET_break (0);
-    GST_send_operation_fail_msg (client, op_id, "Peer is being destroyed");
-    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    GST_send_operation_fail_msg (client,
+                                 op_id,
+                                 "Peer is being destroyed");
+    GNUNET_SERVICE_client_continue (client);
     return;
   }
-  cfg = GNUNET_TESTBED_extract_config_ (message);
+  cfg = GNUNET_TESTBED_extract_config_ (&msg->header);
   if (NULL == cfg)
   {
-    GNUNET_break (0);    
-    GST_send_operation_fail_msg (client, op_id, "Compression error");
-    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    GNUNET_break (0);
+    GST_send_operation_fail_msg (client,
+                                 op_id,
+                                 "Compression error");
+    GNUNET_SERVICE_client_continue (client);
+    return;
+  }
+  if (GNUNET_NO == peer->details.local.is_running)
+  {
+    emsg = update_peer_config (peer,
+                               cfg);
+    if (NULL != emsg)
+      GST_send_operation_fail_msg (client,
+                                   op_id,
+                                   emsg);
+    GST_send_operation_success_msg (client,
+                                    op_id);
+    GNUNET_SERVICE_client_continue (client);
+    GNUNET_free_non_null (emsg);
+    return;
+  }
+  prc = GNUNET_new (struct PeerReconfigureContext);
+  if (GNUNET_OK !=
+      GNUNET_TESTING_peer_stop_async (peer->details.local.peer,
+                                      &prc_stop_cb,
+                                      prc))
+  {
+    GNUNET_assert (0 < GNUNET_asprintf (&emsg,
+                                        "Error trying to stop peer %u asynchronously\n",
+                                        peer_id));
+    LOG (GNUNET_ERROR_TYPE_ERROR,
+         "%s\n",
+         emsg);
+    GST_send_operation_fail_msg (client,
+                                 op_id,
+                                 emsg);
+    GNUNET_SERVICE_client_continue (client);
+    GNUNET_free (prc);
+    GNUNET_free (emsg);
     return;
   }
-  prc = GNUNET_malloc (sizeof (struct PeerReconfigureContext));
   prc->cfg = cfg;
   prc->peer_id = peer_id;
   prc->op_id = op_id;
-  prc->client = client;  
-  GNUNET_SERVER_client_keep (client);
-  GNUNET_CONTAINER_DLL_insert_tail (prc_head, prc_tail, prc);
-  GNUNET_TESTING_peer_stop_async (peer->details.local.peer, prc_stop_cb, prc);
-  GNUNET_SERVER_receive_done (client, GNUNET_OK);
-}
-
-
-/**
- * Cleanup the context information created for managing a peer's service
- *
- * @param mctx the ManageServiceContext
- */
-static void
-cleanup_mctx (struct ManageServiceContext *mctx)
-{
-  mctx->expired = GNUNET_YES;
-  GNUNET_CONTAINER_DLL_remove (mctx_head, mctx_tail, mctx);
-  GNUNET_SERVER_client_drop (mctx->client);
-  GNUNET_ARM_disconnect_and_free (mctx->ah);
-  GNUNET_assert (0 < mctx->peer->reference_cnt);
-  mctx->peer->reference_cnt--;
-  if ( (GNUNET_YES == mctx->peer->destroy_flag)
-       && (0 == mctx->peer->reference_cnt) )
-    GST_destroy_peer (mctx->peer);
-  GNUNET_free (mctx);
+  prc->client = client;
+  GNUNET_CONTAINER_DLL_insert_tail (prc_head,
+                                    prc_tail,
+                                    prc);
+  GNUNET_SERVICE_client_continue (client);
 }
 
 
@@ -948,7 +1130,7 @@ GST_free_mctxq ()
 
 
 /**
- * Returns a string interpretation of 'rs'
+ * Returns a string interpretation of @a rs.
  *
  * @param rs the request status from ARM
  * @return a string interpretation of the request status
@@ -959,24 +1141,17 @@ arm_req_string (enum GNUNET_ARM_RequestStatus rs)
   switch (rs)
   {
   case GNUNET_ARM_REQUEST_SENT_OK:
-    return _("Message was sent successfully");
-  case GNUNET_ARM_REQUEST_CONFIGURATION_ERROR:
-    return _("Misconfiguration (can't connect to the ARM service)");
+    return _ ("Message was sent successfully");
+
   case GNUNET_ARM_REQUEST_DISCONNECTED:
-    return _("We disconnected from ARM before we could send a request");
-  case GNUNET_ARM_REQUEST_BUSY:
-    return _("ARM API is busy");
-  case GNUNET_ARM_REQUEST_TOO_LONG:
-    return _("Request doesn't fit into a message");
-  case GNUNET_ARM_REQUEST_TIMEOUT:
-    return _("Request timed out");
+    return _ ("We disconnected from ARM before we could send a request");
   }
-  return _("Unknown request status");
+  return _ ("Unknown request status");
 }
 
 
 /**
- * Returns a string interpretation of the 'result'
+ * Returns a string interpretation of the @a result.
  *
  * @param result the arm result
  * @return a string interpretation
@@ -987,27 +1162,36 @@ arm_ret_string (enum GNUNET_ARM_Result result)
   switch (result)
   {
   case GNUNET_ARM_RESULT_STOPPED:
-    return _("%s is stopped");
+    return _ ("%s is stopped");
+
   case GNUNET_ARM_RESULT_STARTING:
-    return _("%s is starting");
+    return _ ("%s is starting");
+
   case GNUNET_ARM_RESULT_STOPPING:
-    return _("%s is stopping");
+    return _ ("%s is stopping");
+
   case GNUNET_ARM_RESULT_IS_STARTING_ALREADY:
-    return _("%s is starting already");
+    return _ ("%s is starting already");
+
   case GNUNET_ARM_RESULT_IS_STOPPING_ALREADY:
-    return _("%s is stopping already");
+    return _ ("%s is stopping already");
+
   case GNUNET_ARM_RESULT_IS_STARTED_ALREADY:
-    return _("%s is started already");
+    return _ ("%s is started already");
+
   case GNUNET_ARM_RESULT_IS_STOPPED_ALREADY:
-    return _("%s is stopped already");
+    return _ ("%s is stopped already");
+
   case GNUNET_ARM_RESULT_IS_NOT_KNOWN:
-    return _("%s service is not known to ARM");
+    return _ ("%s service is not known to ARM");
+
   case GNUNET_ARM_RESULT_START_FAILED:
-    return _("%s service failed to start");
+    return _ ("%s service failed to start");
+
   case GNUNET_ARM_RESULT_IN_SHUTDOWN:
-    return _("%s service can't be started because ARM is shutting down");
+    return _ ("%s service can't be started because ARM is shutting down");
   }
-  return _("%.s Unknown result code.");
+  return _ ("%.s Unknown result code.");
 }
 
 
@@ -1015,17 +1199,16 @@ arm_ret_string (enum GNUNET_ARM_Result result)
  * Function called in response to a start/stop request.
  * Will be called when request was not sent successfully,
  * or when a reply comes. If the request was not sent successfully,
- * 'rs' will indicate that, and 'service' and 'result' will be undefined.
+ * @a rs will indicate that, and @a result will be undefined.
  *
  * @param cls ManageServiceContext
  * @param rs status of the request
- * @param service service name
  * @param result result of the operation
  */
 static void
-service_manage_result_cb (void *cls, 
-                          enum GNUNET_ARM_RequestStatus rs, 
-                          const char *service, enum GNUNET_ARM_Result result)
+service_manage_result_cb (void *cls,
+                          enum GNUNET_ARM_RequestStatus rs,
+                          enum GNUNET_ARM_Result result)
 {
   struct ManageServiceContext *mctx = cls;
   char *emsg;
@@ -1035,93 +1218,111 @@ service_manage_result_cb (void *cls,
     return;
   if (GNUNET_ARM_REQUEST_SENT_OK != rs)
   {
-    GNUNET_asprintf (&emsg, "Error communicating with Peer %u's ARM: %s",
-                     mctx->peer->id, arm_req_string (rs));
+    GNUNET_asprintf (&emsg,
+                     "Error communicating with Peer %u's ARM: %s",
+                     mctx->peer->id,
+                     arm_req_string (rs));
     goto ret;
   }
   if (1 == mctx->start)
     goto service_start_check;
   if (! ((GNUNET_ARM_RESULT_STOPPED == result)
-            || (GNUNET_ARM_RESULT_STOPPING == result)
-            || (GNUNET_ARM_RESULT_IS_STOPPING_ALREADY == result)
-            || (GNUNET_ARM_RESULT_IS_STOPPED_ALREADY == result)) )
+         || (GNUNET_ARM_RESULT_STOPPING == result)
+         || (GNUNET_ARM_RESULT_IS_STOPPING_ALREADY == result)
+         || (GNUNET_ARM_RESULT_IS_STOPPED_ALREADY == result)))
   {
     /* stopping a service failed */
-    GNUNET_asprintf (&emsg, arm_ret_string (result), service);
+    GNUNET_asprintf (&emsg,
+                     arm_ret_string (result),
+                     mctx->service);
     goto ret;
   }
   /* service stopped successfully */
   goto ret;
 
- service_start_check:
+service_start_check:
   if (! ((GNUNET_ARM_RESULT_STARTING == result)
-            || (GNUNET_ARM_RESULT_IS_STARTING_ALREADY == result)
-            || (GNUNET_ARM_RESULT_IS_STARTED_ALREADY == result)) )
+         || (GNUNET_ARM_RESULT_IS_STARTING_ALREADY == result)
+         || (GNUNET_ARM_RESULT_IS_STARTED_ALREADY == result)))
   {
     /* starting a service failed */
-    GNUNET_asprintf (&emsg, arm_ret_string (result), service);
+    GNUNET_asprintf (&emsg,
+                     arm_ret_string (result),
+                     mctx->service);
     goto ret;
   }
   /* service started successfully */
-  
- ret:
+
+ret:
   if (NULL != emsg)
   {
     LOG_DEBUG ("%s\n", emsg);
-    GST_send_operation_fail_msg (mctx->client, mctx->op_id, emsg);
+    GST_send_operation_fail_msg (mctx->client,
+                                 mctx->op_id,
+                                 emsg);
   }
   else
-    GST_send_operation_success_msg (mctx->client, mctx->op_id);
+    GST_send_operation_success_msg (mctx->client,
+                                    mctx->op_id);
   GNUNET_free_non_null (emsg);
   cleanup_mctx (mctx);
 }
 
 
 /**
- * Handler for GNUNET_TESTBED_ManagePeerServiceMessage message
+ * Check #GNUNET_MESSAGE_TYPE_TESTBED_MANAGE_PEER_SERVICE message
  *
- * @param cls NULL
- * @param client identification of client
- * @param message the actual message
+ * @param cls identification of client
+ * @param msg the actual message
+ * @return #GNUNET_OK if @a msg is well-formed
  */
-void
-GST_handle_manage_peer_service (void *cls, struct GNUNET_SERVER_Client *client,
-                                const struct GNUNET_MessageHeader *message)
+int
+check_manage_peer_service (void *cls,
+                           const struct
+                           GNUNET_TESTBED_ManagePeerServiceMessage *msg)
 {
-  const struct GNUNET_TESTBED_ManagePeerServiceMessage *msg;
-  const char* service;
-  struct Peer *peer;
-  char *emsg;
-  struct GNUNET_ARM_Handle *ah;
-  struct ManageServiceContext *mctx;
-  struct ForwardedOperationContext *fopc;
-  uint64_t op_id;
-  uint32_t peer_id;
   uint16_t msize;
-  
+  const char*service;
 
-  msize = ntohs (message->size);
-  if (msize <= sizeof (struct GNUNET_TESTBED_ManagePeerServiceMessage))
-  {
-    GNUNET_break_op (0);  
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
-    return;
-  }
-  msg = (const struct GNUNET_TESTBED_ManagePeerServiceMessage *) message;
-  service = (const char *) &msg[1];  
+  msize = ntohs (msg->header.size);
+  service = (const char *) &msg[1];
   if ('\0' != service[msize - sizeof
                       (struct GNUNET_TESTBED_ManagePeerServiceMessage) - 1])
   {
     GNUNET_break_op (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
-    return;
+    return GNUNET_SYSERR;
   }
   if (1 < msg->start)
   {
     GNUNET_break_op (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
-    return;    
+    return GNUNET_SYSERR;
   }
+  return GNUNET_OK;
+}
+
+
+/**
+ * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_MANAGE_PEER_SERVICE messages
+ *
+ * @param cls identification of client
+ * @param msg the actual message
+ */
+void
+handle_manage_peer_service (void *cls,
+                            const struct
+                            GNUNET_TESTBED_ManagePeerServiceMessage *msg)
+{
+  struct GNUNET_SERVICE_Client *client = cls;
+  const char*service;
+  struct Peer *peer;
+  char *emsg;
+  struct GNUNET_ARM_Handle *ah;
+  struct ManageServiceContext *mctx;
+  struct ForwardedOperationContext *fopc;
+  uint64_t op_id;
+  uint32_t peer_id;
+
+  service = (const char *) &msg[1];
   peer_id = ntohl (msg->peer_id);
   op_id = GNUNET_ntohll (msg->operation_id);
   LOG_DEBUG ("Received request to manage service %s on peer %u\n",
@@ -1142,28 +1343,37 @@ GST_handle_manage_peer_service (void *cls, struct GNUNET_SERVER_Client *client,
   if (GNUNET_YES == peer->is_remote)
   {
     /* Forward the destory message to sub controller */
-    fopc = GNUNET_malloc (sizeof (struct ForwardedOperationContext));
-    GNUNET_SERVER_client_keep (client);
+    fopc = GNUNET_new (struct ForwardedOperationContext);
     fopc->client = client;
     fopc->cls = peer;
     fopc->type = OP_MANAGE_SERVICE;
     fopc->operation_id = op_id;
     fopc->opc =
-        GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote.
-                                               slave->controller,
-                                               fopc->operation_id, &msg->header,
-                                               &GST_forwarded_operation_reply_relay,
-                                               fopc);
+      GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote.
+                                             slave->controller,
+                                             fopc->operation_id,
+                                             &msg->header,
+                                             &
+                                             GST_forwarded_operation_reply_relay,
+                                             fopc);
     fopc->timeout_task =
-        GNUNET_SCHEDULER_add_delayed (GST_timeout, &GST_forwarded_operation_timeout,
+      GNUNET_SCHEDULER_add_delayed (GST_timeout,
+                                    &GST_forwarded_operation_timeout,
+                                    fopc);
+    GNUNET_CONTAINER_DLL_insert_tail (fopcq_head,
+                                      fopcq_tail,
                                       fopc);
-    GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc);
-    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    GNUNET_SERVICE_client_continue (client);
     return;
   }
+  if (GNUNET_NO == peer->details.local.is_running)
+  {
+    emsg = GNUNET_strdup ("Peer not running\n");
+    goto err_ret;
+  }
   if ((0 != peer->reference_cnt)
-      && ( (0 == strcasecmp ("core", service))
-           || (0 == strcasecmp ("transport", service)) )  )
+      && ((0 == strcasecmp ("core", service))
+          || (0 == strcasecmp ("transport", service))))
   {
     GNUNET_asprintf (&emsg, "Cannot stop %s service of peer with id: %u "
                      "since it is required by existing operations",
@@ -1178,34 +1388,35 @@ GST_handle_manage_peer_service (void *cls, struct GNUNET_SERVER_Client *client,
                      peer_id);
     goto err_ret;
   }
-  mctx = GNUNET_malloc (sizeof (struct ManageServiceContext));
+  mctx = GNUNET_new (struct ManageServiceContext);
   mctx->peer = peer;
   peer->reference_cnt++;
   mctx->op_id = op_id;
   mctx->ah = ah;
-  GNUNET_SERVER_client_keep (client);
   mctx->client = client;
   mctx->start = msg->start;
-  GNUNET_CONTAINER_DLL_insert_tail (mctx_head, mctx_tail, mctx);
+  mctx->service = GNUNET_strdup (service);
+  GNUNET_CONTAINER_DLL_insert_tail (mctx_head,
+                                    mctx_tail,
+                                    mctx);
   if (1 == mctx->start)
-    GNUNET_ARM_request_service_start (mctx->ah, service,
+    GNUNET_ARM_request_service_start (mctx->ah,
+                                      service,
                                       GNUNET_OS_INHERIT_STD_ERR,
-                                      GST_timeout,
-                                      service_manage_result_cb,
+                                      &service_manage_result_cb,
                                       mctx);
   else
     GNUNET_ARM_request_service_stop (mctx->ah, service,
-                                     GST_timeout,
-                                     service_manage_result_cb,
+                                     &service_manage_result_cb,
                                      mctx);
-  GNUNET_SERVER_receive_done (client, GNUNET_OK);
+  GNUNET_SERVICE_client_continue (client);
   return;
 
- err_ret:
+err_ret:
   LOG (GNUNET_ERROR_TYPE_ERROR, "%s\n", emsg);
   GST_send_operation_fail_msg (client, op_id, emsg);
   GNUNET_free (emsg);
-  GNUNET_SERVER_receive_done (client, GNUNET_OK);
+  GNUNET_SERVICE_client_continue (client);
 }
 
 
@@ -1238,7 +1449,7 @@ GST_destroy_peers ()
   {
     peer = GST_peer_list[id];
     if (NULL == peer)
-      continue;    
+      continue;
     if (GNUNET_NO == peer->is_remote)
     {
       if (GNUNET_YES == peer->details.local.is_running)
@@ -1254,38 +1465,6 @@ GST_destroy_peers ()
 }
 
 
-/**
- * Task run upon timeout of forwarded SHUTDOWN_PEERS operation
- *
- * @param cls the ForwardedOperationContext
- * @param tc the scheduler task context
- */
-static void
-shutdown_peers_timeout_cb (void *cls,
-                           const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
-  struct ForwardedOperationContext *fo_ctxt = cls;
-  struct HandlerContext_ShutdownPeers *hc;
-
-  fo_ctxt->timeout_task = GNUNET_SCHEDULER_NO_TASK;
-  hc = fo_ctxt->cls;
-  hc->timeout = GNUNET_YES;
-  GNUNET_assert (0 < hc->nslaves);
-  hc->nslaves--;
-  if (0 == hc->nslaves)
-  {
-    GST_send_operation_fail_msg (fo_ctxt->client, fo_ctxt->operation_id,
-                                 "Timeout at a slave controller");
-    GNUNET_free (hc);
-    hc = NULL;
-  }
-  GNUNET_TESTBED_forward_operation_msg_cancel_ (fo_ctxt->opc);  
-  GNUNET_SERVER_client_drop (fo_ctxt->client);
-  GNUNET_CONTAINER_DLL_remove (fopcq_head, fopcq_tail, fo_ctxt);
-  GNUNET_free (fo_ctxt);
-}
-
-
 /**
  * The reply msg handler forwarded SHUTDOWN_PEERS operation.  Checks if a
  * success reply is received from all clients and then sends the success message
@@ -1300,60 +1479,58 @@ shutdown_peers_reply_cb (void *cls,
 {
   struct ForwardedOperationContext *fo_ctxt = cls;
   struct HandlerContext_ShutdownPeers *hc;
-  
+
   hc = fo_ctxt->cls;
-  GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != fo_ctxt->timeout_task);
-  GNUNET_SCHEDULER_cancel (fo_ctxt->timeout_task);
-  fo_ctxt->timeout_task = GNUNET_SCHEDULER_NO_TASK;
   GNUNET_assert (0 < hc->nslaves);
   hc->nslaves--;
-  if (GNUNET_MESSAGE_TYPE_TESTBED_GENERIC_OPERATION_SUCCESS != 
+  if (GNUNET_MESSAGE_TYPE_TESTBED_GENERIC_OPERATION_SUCCESS !=
       ntohs (msg->type))
     hc->timeout = GNUNET_YES;
   if (0 == hc->nslaves)
   {
     if (GNUNET_YES == hc->timeout)
-      GST_send_operation_fail_msg (fo_ctxt->client, fo_ctxt->operation_id,
+      GST_send_operation_fail_msg (fo_ctxt->client,
+                                   fo_ctxt->operation_id,
                                    "Timeout at a slave controller");
     else
-      GST_send_operation_success_msg (fo_ctxt->client, fo_ctxt->operation_id);
+      GST_send_operation_success_msg (fo_ctxt->client,
+                                      fo_ctxt->operation_id);
     GNUNET_free (hc);
     hc = NULL;
   }
-  GNUNET_SERVER_client_drop (fo_ctxt->client);
-  GNUNET_CONTAINER_DLL_remove (fopcq_head, fopcq_tail, fo_ctxt);
+  GNUNET_CONTAINER_DLL_remove (fopcq_head,
+                               fopcq_tail,
+                               fo_ctxt);
   GNUNET_free (fo_ctxt);
 }
 
 
 /**
- * Handler for GNUNET_MESSAGE_TYPE_TESTBED_SHUTDOWN_PEERS messages
+ * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_SHUTDOWN_PEERS messages
  *
- * @param cls NULL
- * @param client identification of the client
- * @param message the actual message
+ * @param cls identification of the client
+ * @param msg the actual message
  */
 void
-GST_handle_shutdown_peers (void *cls, struct GNUNET_SERVER_Client *client,
-                           const struct GNUNET_MessageHeader *message)
+handle_shutdown_peers (void *cls,
+                       const struct GNUNET_TESTBED_ShutdownPeersMessage *msg)
 {
-  const struct GNUNET_TESTBED_ShutdownPeersMessage *msg;
+  struct GNUNET_SERVICE_Client *client = cls;
   struct HandlerContext_ShutdownPeers *hc;
   struct Slave *slave;
   struct ForwardedOperationContext *fo_ctxt;
   uint64_t op_id;
   unsigned int cnt;
 
-  msg = (const struct GNUNET_TESTBED_ShutdownPeersMessage *) message;
   LOG_DEBUG ("Received SHUTDOWN_PEERS\n");
-    /* Stop and destroy all peers */
+  /* Stop and destroy all peers */
   GST_free_mctxq ();
   GST_free_occq ();
   GST_free_roccq ();
   GST_clear_fopcq ();
   /* Forward to all slaves which we have started */
   op_id = GNUNET_ntohll (msg->operation_id);
-  hc = GNUNET_malloc (sizeof (struct HandlerContext_ShutdownPeers));
+  hc = GNUNET_new (struct HandlerContext_ShutdownPeers);
   /* FIXME: have a better implementation where we track which slaves are
      started by this controller */
   for (cnt = 0; cnt < GST_slave_list_size; cnt++)
@@ -1361,33 +1538,32 @@ GST_handle_shutdown_peers (void *cls, struct GNUNET_SERVER_Client *client,
     slave = GST_slave_list[cnt];
     if (NULL == slave)
       continue;
-    if (NULL == slave->controller_proc) /* We didn't start the slave */
+    if (NULL == slave->controller_proc)   /* We didn't start the slave */
       continue;
     LOG_DEBUG ("Forwarding SHUTDOWN_PEERS\n");
     hc->nslaves++;
-    fo_ctxt = GNUNET_malloc (sizeof (struct ForwardedOperationContext));
-    GNUNET_SERVER_client_keep (client);
+    fo_ctxt = GNUNET_new (struct ForwardedOperationContext);
     fo_ctxt->client = client;
     fo_ctxt->operation_id = op_id;
     fo_ctxt->cls = hc;
     fo_ctxt->type = OP_SHUTDOWN_PEERS;
     fo_ctxt->opc =
-        GNUNET_TESTBED_forward_operation_msg_ (slave->controller,
-                                               fo_ctxt->operation_id,
-                                               &msg->header,
-                                               shutdown_peers_reply_cb,
-                                               fo_ctxt);
-    fo_ctxt->timeout_task =
-        GNUNET_SCHEDULER_add_delayed (GST_timeout, &shutdown_peers_timeout_cb,
+      GNUNET_TESTBED_forward_operation_msg_ (slave->controller,
+                                             fo_ctxt->operation_id,
+                                             &msg->header,
+                                             shutdown_peers_reply_cb,
+                                             fo_ctxt);
+    GNUNET_CONTAINER_DLL_insert_tail (fopcq_head,
+                                      fopcq_tail,
                                       fo_ctxt);
-    GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fo_ctxt);
   }
   LOG_DEBUG ("Shutting down peers\n");
   GST_destroy_peers ();
   if (0 == hc->nslaves)
   {
-    GST_send_operation_success_msg (client, op_id);
+    GST_send_operation_success_msg (client,
+                                    op_id);
     GNUNET_free (hc);
   }
-  GNUNET_SERVER_receive_done (client, GNUNET_OK);  
+  GNUNET_SERVICE_client_continue (client);
 }