migrating testbed to new service API
authorChristian Grothoff <christian@grothoff.org>
Mon, 10 Oct 2016 15:47:00 +0000 (15:47 +0000)
committerChristian Grothoff <christian@grothoff.org>
Mon, 10 Oct 2016 15:47:00 +0000 (15:47 +0000)
14 files changed:
src/testbed/gnunet-service-test-barriers.c
src/testbed/gnunet-service-testbed.c
src/testbed/gnunet-service-testbed.h
src/testbed/gnunet-service-testbed_barriers.c
src/testbed/gnunet-service-testbed_barriers.h
src/testbed/gnunet-service-testbed_links.c
src/testbed/gnunet-service-testbed_links.h
src/testbed/gnunet-service-testbed_oc.c
src/testbed/gnunet-service-testbed_peers.c
src/testbed/test_testbed_api_barriers.c
src/testbed/testbed_api.c
src/testbed/testbed_api_barriers.c
src/util/mq.c
src/util/service_new.c

index ce52496969f3bb793e1e72e65fbda33ae749836d..874c7a363ee08a958dae50f2dd8a624de1e204e1 100644 (file)
@@ -76,7 +76,9 @@ do_shutdown (void *cls)
  *   #GNUNET_OK if the barrier is crossed
  */
 static void
-barrier_wait_cb (void *cls, const char *name, int status)
+barrier_wait_cb (void *cls,
+                 const char *name,
+                 int status)
 {
   GNUNET_break (NULL == cls);
   wh = NULL;
@@ -117,10 +119,12 @@ run (void *cls,
 {
   unsigned int rsec;
 
-  rsec = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, 10);
-  tt = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
-                                    (GNUNET_TIME_UNIT_SECONDS, rsec),
-                                    &do_wait, NULL);
+  rsec = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
+                                   10);
+  tt = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
+                                                                    rsec),
+                                    &do_wait,
+                                     NULL);
   GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
 }
 
@@ -139,6 +143,10 @@ main (int argc, char **argv)
 
   ret =
       GNUNET_PROGRAM_run (argc, argv,
-                          "test-barriers", "nohelp", options, &run, NULL);
+                          "test-barriers",
+                          "nohelp",
+                          options,
+                          &run,
+                          NULL);
   return ret;
 }
index 9e181f85a404d1e32a2a3fa8b78d267f7f913871..39697cb56b2ae7dbb7912dca7265ccd9806bfd78 100644 (file)
@@ -1,6 +1,6 @@
 /*
   This file is part of GNUnet.
-  Copyright (C) 2008--2013 GNUnet e.V.
+  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
@@ -82,129 +82,17 @@ unsigned int GST_peer_list_size;
 /* Local definitions and variables */
 /***********************************/
 
-/**
- * The message queue for sending messages to clients
- */
-struct MessageQueue
-{
-  /**
-   * The message to be sent
-   */
-  struct GNUNET_MessageHeader *msg;
-
-  /**
-   * The client to send the message to
-   */
-  struct GNUNET_SERVER_Client *client;
-
-  /**
-   * next pointer for DLL
-   */
-  struct MessageQueue *next;
-
-  /**
-   * prev pointer for DLL
-   */
-  struct MessageQueue *prev;
-};
-
 /**
  * Our hostname; we give this to all the peers we start
  */
 static char *hostname;
 
-/**
- * Current Transmit Handle; NULL if no notify transmit exists currently
- */
-static struct GNUNET_SERVER_TransmitHandle *transmit_handle;
-
-/**
- * The message queue head
- */
-static struct MessageQueue *mq_head;
-
-/**
- * The message queue tail
- */
-static struct MessageQueue *mq_tail;
-
-
-/**
- * Function called to notify a client about the connection begin ready to queue
- * more data.  "buf" will be NULL and "size" zero if the connection was closed
- * for writing in the meantime.
- *
- * @param cls NULL
- * @param size number of bytes available in buf
- * @param buf where the callee should write the message
- * @return number of bytes written to buf
- */
-static size_t
-transmit_ready_notify (void *cls, size_t size, void *buf)
-{
-  struct MessageQueue *mq_entry;
-
-  transmit_handle = NULL;
-  mq_entry = mq_head;
-  GNUNET_assert (NULL != mq_entry);
-  if (0 == size)
-    return 0;
-  GNUNET_assert (ntohs (mq_entry->msg->size) <= size);
-  size = ntohs (mq_entry->msg->size);
-  GNUNET_memcpy (buf, mq_entry->msg, size);
-  GNUNET_free (mq_entry->msg);
-  GNUNET_SERVER_client_drop (mq_entry->client);
-  GNUNET_CONTAINER_DLL_remove (mq_head, mq_tail, mq_entry);
-  GNUNET_free (mq_entry);
-  mq_entry = mq_head;
-  if (NULL != mq_entry)
-    transmit_handle =
-        GNUNET_SERVER_notify_transmit_ready (mq_entry->client,
-                                             ntohs (mq_entry->msg->size),
-                                             GNUNET_TIME_UNIT_FOREVER_REL,
-                                             &transmit_ready_notify, NULL);
-  return size;
-}
-
-
-/**
- * Queues a message in send queue for sending to the service
- *
- * @param client the client to whom the queued message has to be sent
- * @param msg the message to queue
- */
-void
-GST_queue_message (struct GNUNET_SERVER_Client *client,
-                   struct GNUNET_MessageHeader *msg)
-{
-  struct MessageQueue *mq_entry;
-  uint16_t type;
-  uint16_t size;
-
-  type = ntohs (msg->type);
-  size = ntohs (msg->size);
-  GNUNET_assert ((GNUNET_MESSAGE_TYPE_TESTBED_INIT <= type) &&
-                 (GNUNET_MESSAGE_TYPE_TESTBED_MAX > type));
-  mq_entry = GNUNET_new (struct MessageQueue);
-  mq_entry->msg = msg;
-  mq_entry->client = client;
-  GNUNET_SERVER_client_keep (client);
-  LOG_DEBUG ("Queueing message of type %u, size %u for sending\n", type,
-             ntohs (msg->size));
-  GNUNET_CONTAINER_DLL_insert_tail (mq_head, mq_tail, mq_entry);
-  if (NULL == transmit_handle)
-    transmit_handle =
-        GNUNET_SERVER_notify_transmit_ready (client, size,
-                                             GNUNET_TIME_UNIT_FOREVER_REL,
-                                             &transmit_ready_notify, NULL);
-}
-
 
 /**
  * Function to add a host to the current list of known hosts
  *
  * @param host the host to add
- * @return GNUNET_OK on success; GNUNET_SYSERR on failure due to host-id
+ * @return #GNUNET_OK on success; #GNUNET_SYSERR on failure due to host-id
  *           already in use
  */
 static int
@@ -233,24 +121,25 @@ host_list_add (struct GNUNET_TESTBED_Host *host)
  * @param emsg the error message; can be NULL
  */
 void
-GST_send_operation_fail_msg (struct GNUNET_SERVER_Client *client,
-                             uint64_t operation_id, const char *emsg)
+GST_send_operation_fail_msg (struct GNUNET_SERVICE_Client *client,
+                             uint64_t operation_id,
+                             const char *emsg)
 {
+  struct GNUNET_MQ_Envelope *env;
   struct GNUNET_TESTBED_OperationFailureEventMessage *msg;
-  uint16_t msize;
   uint16_t emsg_len;
 
-  msize = sizeof (struct GNUNET_TESTBED_OperationFailureEventMessage);
   emsg_len = (NULL == emsg) ? 0 : strlen (emsg) + 1;
-  msize += emsg_len;
-  msg = GNUNET_malloc (msize);
-  msg->header.size = htons (msize);
-  msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_OPERATION_FAIL_EVENT);
+  env = GNUNET_MQ_msg_extra (msg,
+                             emsg_len,
+                             GNUNET_MESSAGE_TYPE_TESTBED_OPERATION_FAIL_EVENT);
   msg->event_type = htonl (GNUNET_TESTBED_ET_OPERATION_FINISHED);
   msg->operation_id = GNUNET_htonll (operation_id);
-  if (0 != emsg_len)
-    GNUNET_memcpy (&msg[1], emsg, emsg_len);
-  GST_queue_message (client, &msg->header);
+  GNUNET_memcpy (&msg[1],
+                 emsg,
+                 emsg_len);
+  GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
+                  env);
 }
 
 
@@ -261,22 +150,21 @@ GST_send_operation_fail_msg (struct GNUNET_SERVER_Client *client,
  * @param operation_id the id of the operation which was successful
  */
 void
-GST_send_operation_success_msg (struct GNUNET_SERVER_Client *client,
+GST_send_operation_success_msg (struct GNUNET_SERVICE_Client *client,
                                 uint64_t operation_id)
 {
+  struct GNUNET_MQ_Envelope *env;
   struct GNUNET_TESTBED_GenericOperationSuccessEventMessage *msg;
-  uint16_t msize;
 
-  msize = sizeof (struct GNUNET_TESTBED_GenericOperationSuccessEventMessage);
-  msg = GNUNET_malloc (msize);
-  msg->header.size = htons (msize);
-  msg->header.type =
-      htons (GNUNET_MESSAGE_TYPE_TESTBED_GENERIC_OPERATION_SUCCESS);
+  env = GNUNET_MQ_msg (msg,
+                       GNUNET_MESSAGE_TYPE_TESTBED_GENERIC_OPERATION_SUCCESS);
   msg->operation_id = GNUNET_htonll (operation_id);
   msg->event_type = htonl (GNUNET_TESTBED_ET_OPERATION_FINISHED);
-  GST_queue_message (client, &msg->header);
+  GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
+                  env);
 }
 
+
 /**
  * Callback which will be called after a host registration succeeded or failed
  *
@@ -284,7 +172,8 @@ GST_send_operation_success_msg (struct GNUNET_SERVER_Client *client,
  * @param emsg the error message; NULL if host registration is successful
  */
 static void
-hr_completion (void *cls, const char *emsg);
+hr_completion (void *cls,
+               const char *emsg);
 
 
 /**
@@ -304,8 +193,10 @@ register_next_host (struct Slave *slave)
   LOG (GNUNET_ERROR_TYPE_DEBUG, "Registering host %u at %u\n",
        GNUNET_TESTBED_host_get_id_ (hr->host),
        GNUNET_TESTBED_host_get_id_ (GST_host_list[slave->host_id]));
-  slave->rhandle =
-      GNUNET_TESTBED_register_host (slave->controller, hr->host, hr_completion,
+  slave->rhandle
+    = GNUNET_TESTBED_register_host (slave->controller,
+                                    hr->host,
+                                    hr_completion,
                                     slave);
 }
 
@@ -317,7 +208,8 @@ register_next_host (struct Slave *slave)
  * @param emsg the error message; NULL if host registration is successful
  */
 static void
-hr_completion (void *cls, const char *emsg)
+hr_completion (void *cls,
+               const char *emsg)
 {
   struct Slave *slave = cls;
   struct HostRegistration *hr;
@@ -325,12 +217,16 @@ hr_completion (void *cls, const char *emsg)
   slave->rhandle = NULL;
   hr = slave->hr_dll_head;
   GNUNET_assert (NULL != hr);
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "Registering host %u at %u successful\n",
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Registering host %u at %u successful\n",
        GNUNET_TESTBED_host_get_id_ (hr->host),
        GNUNET_TESTBED_host_get_id_ (GST_host_list[slave->host_id]));
-  GNUNET_CONTAINER_DLL_remove (slave->hr_dll_head, slave->hr_dll_tail, hr);
+  GNUNET_CONTAINER_DLL_remove (slave->hr_dll_head,
+                               slave->hr_dll_tail,
+                               hr);
   if (NULL != hr->cb)
-    hr->cb (hr->cb_cls, emsg);
+    hr->cb (hr->cb_cls,
+            emsg);
   GNUNET_free (hr);
   if (NULL != slave->hr_dll_head)
     register_next_host (slave);
@@ -349,7 +245,8 @@ hr_completion (void *cls, const char *emsg)
 void
 GST_queue_host_registration (struct Slave *slave,
                              GNUNET_TESTBED_HostRegistrationCompletion cb,
-                             void *cb_cls, struct GNUNET_TESTBED_Host *host)
+                             void *cb_cls,
+                             struct GNUNET_TESTBED_Host *host)
 {
   struct HostRegistration *hr;
   int call_register;
@@ -363,7 +260,9 @@ GST_queue_host_registration (struct Slave *slave,
   hr->cb_cls = cb_cls;
   hr->host = host;
   call_register = (NULL == slave->hr_dll_head) ? GNUNET_YES : GNUNET_NO;
-  GNUNET_CONTAINER_DLL_insert_tail (slave->hr_dll_head, slave->hr_dll_tail, hr);
+  GNUNET_CONTAINER_DLL_insert_tail (slave->hr_dll_head,
+                                    slave->hr_dll_tail,
+                                    hr);
   if (GNUNET_YES == call_register)
     register_next_host (slave);
 }
@@ -380,23 +279,24 @@ GST_forwarded_operation_reply_relay (void *cls,
                                      const struct GNUNET_MessageHeader *msg)
 {
   struct ForwardedOperationContext *fopc = cls;
-  struct GNUNET_MessageHeader *dup_msg;
-  uint16_t msize;
+  struct GNUNET_MQ_Envelope *env;
 
-  msize = ntohs (msg->size);
-  LOG_DEBUG ("Relaying message with type: %u, size: %u\n", ntohs (msg->type),
-             msize);
-  dup_msg = GNUNET_copy_message (msg);
-  GST_queue_message (fopc->client, dup_msg);
-  GNUNET_SERVER_client_drop (fopc->client);
+  LOG_DEBUG ("Relaying message with type: %u, size: %u\n",
+             ntohs (msg->type),
+             ntohs (msg->size));
+  env = GNUNET_MQ_msg_copy (msg);
+  GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (fopc->client),
+                  env);
   GNUNET_SCHEDULER_cancel (fopc->timeout_task);
-  GNUNET_CONTAINER_DLL_remove (fopcq_head, fopcq_tail, fopc);
+  GNUNET_CONTAINER_DLL_remove (fopcq_head,
+                               fopcq_tail,
+                               fopc);
   GNUNET_free (fopc);
 }
 
 
 /**
- * Task to free resources when forwarded operation has been timedout
+ * Task to free resources when forwarded operation has been timed out
  *
  * @param cls the ForwardedOperationContext
  */
@@ -405,12 +305,16 @@ GST_forwarded_operation_timeout (void *cls)
 {
   struct ForwardedOperationContext *fopc = cls;
 
+  fopc->timeout_task = NULL;
   GNUNET_TESTBED_forward_operation_msg_cancel_ (fopc->opc);
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "A forwarded operation has timed out\n");
-  GST_send_operation_fail_msg (fopc->client, fopc->operation_id,
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "A forwarded operation has timed out\n");
+  GST_send_operation_fail_msg (fopc->client,
+                               fopc->operation_id,
                                "A forwarded operation has timed out");
-  GNUNET_SERVER_client_drop (fopc->client);
-  GNUNET_CONTAINER_DLL_remove (fopcq_head, fopcq_tail, fopc);
+  GNUNET_CONTAINER_DLL_remove (fopcq_head,
+                               fopcq_tail,
+                               fopc);
   GNUNET_free (fopc);
 }
 
@@ -425,7 +329,8 @@ GST_forwarded_operation_timeout (void *cls)
  *           upon empty service sharing specification.
  */
 static struct GNUNET_TESTING_SharedService *
-parse_shared_services (char *ss_str, struct GNUNET_CONFIGURATION_Handle *cfg)
+parse_shared_services (char *ss_str,
+                       struct GNUNET_CONFIGURATION_Handle *cfg)
 {
   struct GNUNET_TESTING_SharedService ss;
   struct GNUNET_TESTING_SharedService *slist;
@@ -446,19 +351,27 @@ parse_shared_services (char *ss_str, struct GNUNET_CONFIGURATION_Handle *cfg)
   {
     ss.service = NULL;
     ss.share = 0;
-    if (2 != sscanf (arg, "%255[^:]:%u", service, &ss.share))
+    if (2 != sscanf (arg, "%255[^:]:%u",
+                     service,
+                     &ss.share))
     {
-      LOG (GNUNET_ERROR_TYPE_WARNING, "Ignoring shared service spec: %s", arg);
+      LOG (GNUNET_ERROR_TYPE_WARNING,
+           "Ignoring shared service spec: %s",
+           arg);
       continue;
     }
-    LOG_DEBUG ("Will be sharing %s service among %u peers\n", service, ss.share);
+    LOG_DEBUG ("Will be sharing %s service among %u peers\n",
+               service,
+               ss.share);
     ss.service = GNUNET_strdup (service);
     GROW_SS;
   }
   if (NULL != slist)
   {
     /* Add trailing NULL block */
-    (void) memset (&ss, 0, sizeof (struct GNUNET_TESTING_SharedService));
+    (void) memset (&ss,
+                   0,
+                   sizeof (struct GNUNET_TESTING_SharedService));
     GROW_SS;
   }
   return slist;
@@ -467,66 +380,78 @@ parse_shared_services (char *ss_str, struct GNUNET_CONFIGURATION_Handle *cfg)
 
 
 /**
- * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_INIT messages
+ * Check #GNUNET_MESSAGE_TYPE_TESTBED_INIT messages
  *
- * @param cls NULL
- * @param client identification of the client
+ * @param cls identification of the client
+ * @param message the actual message
+ * @return #GNUNET_OK if @a message is well-formed
+ */
+static int
+check_init (void *cls,
+            const struct GNUNET_TESTBED_InitMessage *msg)
+{
+  const char *controller_hostname;
+  uint16_t msize;
+
+  msize = ntohs (msg->header.size) - sizeof (struct GNUNET_TESTBED_InitMessage);
+  controller_hostname = (const char *) &msg[1];
+  if ('\0' != controller_hostname[msize - 1])
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+
+/**
+ * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_INIT messages
+ *
+ * @param cls identification of the client
  * @param message the actual message
  */
 static void
 handle_init (void *cls,
-            struct GNUNET_SERVER_Client *client,
-             const struct GNUNET_MessageHeader *message)
+             const struct GNUNET_TESTBED_InitMessage *msg)
 {
-  const struct GNUNET_TESTBED_InitMessage *msg;
+  struct GNUNET_SERVICE_Client *client = cls;
   struct GNUNET_TESTBED_Host *host;
   const char *controller_hostname;
   char *ss_str;
   struct GNUNET_TESTING_SharedService *ss;
   unsigned int cnt;
-  uint16_t msize;
 
   if (NULL != GST_context)
   {
     LOG_DEBUG ("We are being connected to laterally\n");
-    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    GNUNET_SERVICE_client_continue (client);
     return;
   }
-  msg = (const struct GNUNET_TESTBED_InitMessage *) message;
-  msize = ntohs (message->size);
-  if (msize <= sizeof (struct GNUNET_TESTBED_InitMessage))
-  {
-    GNUNET_break (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
-    return;
-  }
-  msize -= sizeof (struct GNUNET_TESTBED_InitMessage);
   controller_hostname = (const char *) &msg[1];
-  if ('\0' != controller_hostname[msize - 1])
-  {
-    GNUNET_break (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
-    return;
-  }
   ss_str = NULL;
   ss = NULL;
-  if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (GST_config, "TESTBED",
-                                                          "SHARED_SERVICES",
-                                                          &ss_str))
+  if (GNUNET_OK ==
+      GNUNET_CONFIGURATION_get_value_string (GST_config,
+                                             "TESTBED",
+                                             "SHARED_SERVICES",
+                                             &ss_str))
   {
-    ss = parse_shared_services (ss_str, GST_config);
+    ss = parse_shared_services (ss_str,
+                                GST_config);
     GNUNET_free (ss_str);
     ss_str = NULL;
   }
   GST_context = GNUNET_new (struct Context);
-  GNUNET_SERVER_client_keep (client);
   GST_context->client = client;
   GST_context->host_id = ntohl (msg->host_id);
   GST_context->master_ip = GNUNET_strdup (controller_hostname);
-  LOG_DEBUG ("Our IP: %s\n", GST_context->master_ip);
-  GST_context->system =
-      GNUNET_TESTING_system_create ("testbed", GST_context->master_ip,
-                                    hostname, ss);
+  LOG_DEBUG ("Our IP: %s\n",
+             GST_context->master_ip);
+  GST_context->system
+    = GNUNET_TESTING_system_create ("testbed",
+                                    GST_context->master_ip,
+                                    hostname,
+                                    ss);
   if (NULL != ss)
   {
     for (cnt = 0; NULL != ss[cnt].service; cnt++)
@@ -539,28 +464,64 @@ handle_init (void *cls,
   }
   host =
       GNUNET_TESTBED_host_create_with_id (GST_context->host_id,
-                                          GST_context->master_ip, NULL,
-                                          GST_config, 0);
+                                          GST_context->master_ip,
+                                          NULL,
+                                          GST_config,
+                                          0);
   host_list_add (host);
-  LOG_DEBUG ("Created master context with host ID: %u\n", GST_context->host_id);
-  GNUNET_SERVER_receive_done (client, GNUNET_OK);
+  LOG_DEBUG ("Created master context with host ID: %u\n",
+             GST_context->host_id);
+  GNUNET_SERVICE_client_continue (client);
+}
+
+
+/**
+ * Check #GNUNET_MESSAGE_TYPE_TESTBED_ADDHOST messages
+ *
+ * @param cls identification of the client
+ * @param msg the actual message
+ * @return #GNUNET_OK if @a message is well-formed
+ */
+static int
+check_add_host (void *cls,
+                 const struct GNUNET_TESTBED_AddHostMessage *msg)
+{
+  uint16_t username_length;
+  uint16_t hostname_length;
+  uint16_t msize;
+
+  msize = ntohs (msg->header.size) - sizeof (struct GNUNET_TESTBED_AddHostMessage);
+  username_length = ntohs (msg->username_length);
+  hostname_length = ntohs (msg->hostname_length);
+  /* msg must contain hostname */
+  if ( (msize <= username_length) ||
+       (0 == hostname_length) )
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  /* msg must contain configuration */
+  if (msize <= username_length + hostname_length)
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
 }
 
 
 /**
  * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_ADDHOST 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
  */
 static void
 handle_add_host (void *cls,
-                struct GNUNET_SERVER_Client *client,
-                 const struct GNUNET_MessageHeader *message)
+                 const struct GNUNET_TESTBED_AddHostMessage *msg)
 {
+  struct GNUNET_SERVICE_Client *client = cls;
   struct GNUNET_TESTBED_Host *host;
-  const struct GNUNET_TESTBED_AddHostMessage *msg;
   struct GNUNET_TESTBED_HostConfirmedMessage *reply;
   struct GNUNET_CONFIGURATION_Handle *host_cfg;
   char *username;
@@ -570,36 +531,10 @@ handle_add_host (void *cls,
   uint32_t host_id;
   uint16_t username_length;
   uint16_t hostname_length;
-  uint16_t reply_size;
-  uint16_t msize;
+  struct GNUNET_MQ_Envelope *env;
 
-  msg = (const struct GNUNET_TESTBED_AddHostMessage *) message;
-  msize = ntohs (msg->header.size);
-  if (msize <= sizeof (struct GNUNET_TESTBED_AddHostMessage))
-  {
-    GNUNET_break_op (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
-    return;
-  }
   username_length = ntohs (msg->username_length);
   hostname_length = ntohs (msg->hostname_length);
-  /* msg must contain hostname */
-  if ((msize <= (sizeof (struct GNUNET_TESTBED_AddHostMessage) +
-                 username_length))
-      || (0 == hostname_length))
-  {
-    GNUNET_break_op (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
-    return;
-  }
-  /* msg must contain configuration */
-  if (msize <= (sizeof (struct GNUNET_TESTBED_AddHostMessage) +
-                username_length + hostname_length))
-  {
-    GNUNET_break_op (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
-    return;
-  }
   username = NULL;
   hostname = NULL;
   ptr = &msg[1];
@@ -610,13 +545,15 @@ handle_add_host (void *cls,
     ptr += username_length;
   }
   hostname = GNUNET_malloc (hostname_length + 1);
-  strncpy (hostname, ptr, hostname_length);
-  if (NULL == (host_cfg = GNUNET_TESTBED_extract_config_ (message)))
+  strncpy (hostname,
+           ptr,
+           hostname_length);
+  if (NULL == (host_cfg = GNUNET_TESTBED_extract_config_ (&msg->header)))
   {
     GNUNET_free_non_null (username);
     GNUNET_free_non_null (hostname);
     GNUNET_break_op (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+    GNUNET_SERVICE_client_drop (client);
     return;
   }
   host_id = ntohl (msg->host_id);
@@ -628,94 +565,108 @@ handle_add_host (void *cls,
   else
     LOG_DEBUG ("-------username: <not given>\n");
   LOG_DEBUG ("-------ssh port: %u\n", ntohs (msg->ssh_port));
-  host =
-      GNUNET_TESTBED_host_create_with_id (host_id, hostname, username,
-                                          host_cfg, ntohs (msg->ssh_port));
+  host = GNUNET_TESTBED_host_create_with_id (host_id,
+                                             hostname,
+                                             username,
+                                             host_cfg,
+                                             ntohs (msg->ssh_port));
   GNUNET_free_non_null (username);
   GNUNET_free (hostname);
   GNUNET_CONFIGURATION_destroy (host_cfg);
   if (NULL == host)
   {
     GNUNET_break_op (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+    GNUNET_SERVICE_client_drop (client);
     return;
   }
-  reply_size = sizeof (struct GNUNET_TESTBED_HostConfirmedMessage);
   if (GNUNET_OK != host_list_add (host))
   {
     /* We are unable to add a host */
     emsg = "A host exists with given host-id";
-    LOG_DEBUG ("%s: %u", emsg, host_id);
+    LOG_DEBUG ("%s: %u",
+               emsg,
+               host_id);
     GNUNET_TESTBED_host_destroy (host);
-    reply_size += strlen (emsg) + 1;
-    reply = GNUNET_malloc (reply_size);
-    GNUNET_memcpy (&reply[1], emsg, strlen (emsg) + 1);
+    env = GNUNET_MQ_msg_extra (reply,
+                               strlen (emsg) + 1,
+                               GNUNET_MESSAGE_TYPE_TESTBED_ADD_HOST_SUCCESS);
+    GNUNET_memcpy (&reply[1],
+                   emsg,
+                   strlen (emsg) + 1);
   }
   else
   {
-    LOG_DEBUG ("Added host %u at %u\n", host_id, GST_context->host_id);
-    reply = GNUNET_malloc (reply_size);
+    LOG_DEBUG ("Added host %u at %u\n",
+               host_id,
+               GST_context->host_id);
+    env = GNUNET_MQ_msg (reply,
+                         GNUNET_MESSAGE_TYPE_TESTBED_ADD_HOST_SUCCESS);
   }
-  reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_ADD_HOST_SUCCESS);
-  reply->header.size = htons (reply_size);
   reply->host_id = htonl (host_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);
 }
 
 
 /**
  * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_GETSLAVECONFIG 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
  */
 static void
 handle_slave_get_config (void *cls,
-                        struct GNUNET_SERVER_Client *client,
-                         const struct GNUNET_MessageHeader *message)
+                         const struct GNUNET_TESTBED_SlaveGetConfigurationMessage *msg)
 {
-  struct GNUNET_TESTBED_SlaveGetConfigurationMessage *msg;
+  struct GNUNET_SERVICE_Client *client = cls;
   struct Slave *slave;
   struct GNUNET_TESTBED_SlaveConfiguration *reply;
   const struct GNUNET_CONFIGURATION_Handle *cfg;
+  struct GNUNET_MQ_Envelope *env;
   char *config;
   char *xconfig;
   size_t config_size;
   size_t xconfig_size;
-  size_t reply_size;
   uint64_t op_id;
   uint32_t slave_id;
 
-  msg = (struct GNUNET_TESTBED_SlaveGetConfigurationMessage *) message;
   slave_id = ntohl (msg->slave_id);
   op_id = GNUNET_ntohll (msg->operation_id);
-  if ((GST_slave_list_size <= slave_id) || (NULL == GST_slave_list[slave_id]))
+  if ( (GST_slave_list_size <= slave_id) ||
+       (NULL == GST_slave_list[slave_id]) )
   {
     /* FIXME: Add forwardings for this type of message here.. */
-    GST_send_operation_fail_msg (client, op_id, "Slave not found");
-    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    GST_send_operation_fail_msg (client,
+                                 op_id,
+                                 "Slave not found");
+    GNUNET_SERVICE_client_continue (client);
     return;
   }
   slave = GST_slave_list[slave_id];
   GNUNET_assert (NULL != (cfg = GNUNET_TESTBED_host_get_cfg_ (GST_host_list[slave->host_id])));
-  config = GNUNET_CONFIGURATION_serialize (cfg, &config_size);
-  xconfig_size =
-      GNUNET_TESTBED_compress_config_ (config, config_size, &xconfig);
+  config = GNUNET_CONFIGURATION_serialize (cfg,
+                                           &config_size);
+  /* FIXME: maybe we want to transmit the delta to the default here? */
+  xconfig_size = GNUNET_TESTBED_compress_config_ (config,
+                                                  config_size,
+                                                  &xconfig);
   GNUNET_free (config);
-  reply_size = xconfig_size + sizeof (struct GNUNET_TESTBED_SlaveConfiguration);
-  GNUNET_break (reply_size <= UINT16_MAX);
-  GNUNET_break (config_size <= UINT16_MAX);
-  reply = GNUNET_realloc (xconfig, reply_size);
-  (void) memmove (&reply[1], reply, xconfig_size);
-  reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_SLAVE_CONFIGURATION);
-  reply->header.size = htons ((uint16_t) reply_size);
+  GNUNET_assert (xconfig_size + sizeof (struct GNUNET_TESTBED_SlaveConfiguration) <= UINT16_MAX);
+  GNUNET_assert (xconfig_size <= UINT16_MAX);
+  env = GNUNET_MQ_msg_extra (reply,
+                             xconfig_size,
+                             GNUNET_MESSAGE_TYPE_TESTBED_SLAVE_CONFIGURATION);
   reply->slave_id = msg->slave_id;
   reply->operation_id = msg->operation_id;
   reply->config_size = htons ((uint16_t) config_size);
-  GST_queue_message (client, &reply->header);
-  GNUNET_SERVER_receive_done (client, GNUNET_OK);
+  GNUNET_memcpy (&reply[1],
+                 xconfig,
+                 xconfig_size);
+  GNUNET_free (xconfig);
+  GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
+                  env);
+  GNUNET_SERVICE_client_continue (client);
 }
 
 
@@ -729,11 +680,12 @@ GST_clear_fopcq ()
 
   while (NULL != (fopc = fopcq_head))
   {
-    GNUNET_CONTAINER_DLL_remove (fopcq_head, fopcq_tail, fopc);
+    GNUNET_CONTAINER_DLL_remove (fopcq_head,
+                                 fopcq_tail,
+                                 fopc);
     GNUNET_TESTBED_forward_operation_msg_cancel_ (fopc->opc);
     if (NULL != fopc->timeout_task)
       GNUNET_SCHEDULER_cancel (fopc->timeout_task);
-    GNUNET_SERVER_client_drop (fopc->client);
     switch (fopc->type)
     {
     case OP_PEER_CREATE:
@@ -775,13 +727,12 @@ GST_clear_fopcq ()
 static void
 shutdown_task (void *cls)
 {
-  struct MessageQueue *mq_entry;
   uint32_t id;
 
   LOG_DEBUG ("Shutting down testbed service\n");
   /* cleanup any remaining forwarded operations */
   GST_clear_fopcq ();
-  GST_free_lcfq ();
+  GST_free_lcf ();
   GST_free_mctxq ();
   GST_free_occq ();
   GST_free_roccq ();
@@ -803,20 +754,11 @@ shutdown_task (void *cls)
   {
     GNUNET_free_non_null (GST_context->master_ip);
     if (NULL != GST_context->system)
-      GNUNET_TESTING_system_destroy (GST_context->system, GNUNET_YES);
-    GNUNET_SERVER_client_drop (GST_context->client);
+      GNUNET_TESTING_system_destroy (GST_context->system,
+                                     GNUNET_YES);
     GNUNET_free (GST_context);
     GST_context = NULL;
   }
-  if (NULL != transmit_handle)
-    GNUNET_SERVER_notify_transmit_ready_cancel (transmit_handle);
-  while (NULL != (mq_entry = mq_head))
-  {
-    GNUNET_free (mq_entry->msg);
-    GNUNET_SERVER_client_drop (mq_entry->client);
-    GNUNET_CONTAINER_DLL_remove (mq_head, mq_tail, mq_entry);
-    GNUNET_free (mq_entry);
-  }
   GNUNET_free_non_null (hostname);
   /* Free hello cache */
   GST_cache_clear ();
@@ -829,20 +771,59 @@ shutdown_task (void *cls)
 }
 
 
+/**
+ * Callback for client connect
+ *
+ * @param cls NULL
+ * @param client the client which has disconnected
+ * @param mq queue for sending messages to @a client
+ * @return @a client
+ */
+static void *
+client_connect_cb (void *cls,
+                   struct GNUNET_SERVICE_Client *client,
+                   struct GNUNET_MQ_Handle *mq)
+{
+  return client;
+}
+
+
 /**
  * Callback for client disconnect
  *
  * @param cls NULL
  * @param client the client which has disconnected
+ * @param app_ctx should match @a client
  */
 static void
-client_disconnect_cb (void *cls, struct GNUNET_SERVER_Client *client)
+client_disconnect_cb (void *cls,
+                      struct GNUNET_SERVICE_Client *client,
+                      void *app_ctx)
 {
+  struct ForwardedOperationContext *fopc;
+  struct ForwardedOperationContext *fopcn;
+
+  GNUNET_assert (client == app_ctx);
+  GST_notify_client_disconnect_oc (client);
+  GST_link_notify_disconnect (client);
+  GST_notify_client_disconnect_peers (client);
+  for (fopc = fopcq_head; NULL != fopc; fopc = fopcn)
+  {
+    fopcn = fopc->next;
+    if (fopc->client == client)
+    {
+      /* handle as if it were a timeout */
+      GNUNET_SCHEDULER_cancel (fopc->timeout_task);
+      GST_forwarded_operation_timeout (fopc);
+    }
+  }
   if (NULL == GST_context)
     return;
   if (client == GST_context->client)
   {
-    LOG (GNUNET_ERROR_TYPE_DEBUG, "Master client disconnected\n");
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Master client disconnected\n");
+    GST_context->client = NULL;
     /* should not be needed as we're terminated by failure to read
      * from stdin, but if stdin fails for some reason, this shouldn't
      * hurt for now --- might need to revise this later if we ever
@@ -857,51 +838,14 @@ client_disconnect_cb (void *cls, struct GNUNET_SERVER_Client *client)
  * Testbed setup
  *
  * @param cls closure
- * @param server the initialized server
  * @param cfg configuration to use
+ * @param service the initialized server
  */
 static void
-testbed_run (void *cls, struct GNUNET_SERVER_Handle *server,
-             const struct GNUNET_CONFIGURATION_Handle *cfg)
+testbed_run (void *cls,
+             const struct GNUNET_CONFIGURATION_Handle *cfg,
+             struct GNUNET_SERVICE_Handle *service)
 {
-  static const struct GNUNET_SERVER_MessageHandler message_handlers[] = {
-    {&handle_init, NULL, GNUNET_MESSAGE_TYPE_TESTBED_INIT, 0},
-    {&handle_add_host, NULL, GNUNET_MESSAGE_TYPE_TESTBED_ADD_HOST, 0},
-    {&GST_handle_link_controllers, NULL,
-     GNUNET_MESSAGE_TYPE_TESTBED_LINK_CONTROLLERS,
-     sizeof (struct GNUNET_TESTBED_ControllerLinkRequest)},
-    {&GST_handle_peer_create, NULL, GNUNET_MESSAGE_TYPE_TESTBED_CREATE_PEER, 0},
-    {&GST_handle_peer_destroy, NULL, GNUNET_MESSAGE_TYPE_TESTBED_DESTROY_PEER,
-     sizeof (struct GNUNET_TESTBED_PeerDestroyMessage)},
-    {&GST_handle_peer_start, NULL, GNUNET_MESSAGE_TYPE_TESTBED_START_PEER,
-     sizeof (struct GNUNET_TESTBED_PeerStartMessage)},
-    {&GST_handle_peer_stop, NULL, GNUNET_MESSAGE_TYPE_TESTBED_STOP_PEER,
-     sizeof (struct GNUNET_TESTBED_PeerStopMessage)},
-    {&GST_handle_peer_get_config, NULL,
-     GNUNET_MESSAGE_TYPE_TESTBED_GET_PEER_INFORMATION,
-     sizeof (struct GNUNET_TESTBED_PeerGetConfigurationMessage)},
-    {&GST_handle_overlay_connect, NULL,
-     GNUNET_MESSAGE_TYPE_TESTBED_OVERLAY_CONNECT,
-     sizeof (struct GNUNET_TESTBED_OverlayConnectMessage)},
-    {&GST_handle_remote_overlay_connect, NULL,
-     GNUNET_MESSAGE_TYPE_TESTBED_REMOTE_OVERLAY_CONNECT, 0},
-    {&GST_handle_manage_peer_service, NULL,
-     GNUNET_MESSAGE_TYPE_TESTBED_MANAGE_PEER_SERVICE, 0},
-    {&handle_slave_get_config, NULL,
-     GNUNET_MESSAGE_TYPE_TESTBED_GET_SLAVE_CONFIGURATION,
-     sizeof (struct GNUNET_TESTBED_SlaveGetConfigurationMessage)},
-    {&GST_handle_shutdown_peers, NULL, GNUNET_MESSAGE_TYPE_TESTBED_SHUTDOWN_PEERS,
-     sizeof (struct GNUNET_TESTBED_ShutdownPeersMessage)},
-    {&GST_handle_peer_reconfigure, NULL,
-     GNUNET_MESSAGE_TYPE_TESTBED_RECONFIGURE_PEER, 0},
-    {&GST_handle_barrier_init, NULL,
-     GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_INIT, 0},
-    {&GST_handle_barrier_cancel, NULL,
-     GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_CANCEL, 0},
-    {&GST_handle_barrier_status, NULL,
-     GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS, 0},
-    {NULL, NULL, 0, 0}
-  };
   char *logfile;
   unsigned long long num;
 
@@ -910,32 +854,40 @@ testbed_run (void *cls, struct GNUNET_SERVER_Handle *server,
       GNUNET_CONFIGURATION_get_value_filename (cfg, "TESTBED", "LOG_FILE",
                                                &logfile))
   {
-    GNUNET_break (GNUNET_OK == GNUNET_log_setup ("testbed", "DEBUG", logfile));
+    GNUNET_break (GNUNET_OK ==
+                  GNUNET_log_setup ("testbed",
+                                    "DEBUG",
+                                    logfile));
     GNUNET_free (logfile);
   }
   GNUNET_assert (GNUNET_OK ==
-                 GNUNET_CONFIGURATION_get_value_number (cfg, "TESTBED",
-                                                        "CACHE_SIZE", &num));
+                 GNUNET_CONFIGURATION_get_value_number (cfg,
+                                                        "TESTBED",
+                                                        "CACHE_SIZE",
+                                                        &num));
   GST_cache_init ((unsigned int) num);
   GST_connection_pool_init ((unsigned int) num);
   GNUNET_assert (GNUNET_OK ==
-                 GNUNET_CONFIGURATION_get_value_number (cfg, "TESTBED",
-                                                        "MAX_OPEN_FDS", &num));
-  GST_opq_openfds = GNUNET_TESTBED_operation_queue_create_
-      (OPERATION_QUEUE_TYPE_FIXED, (unsigned int) num);
+                 GNUNET_CONFIGURATION_get_value_number (cfg,
+                                                        "TESTBED",
+                                                        "MAX_OPEN_FDS",
+                                                        &num));
+  GST_opq_openfds = GNUNET_TESTBED_operation_queue_create_ (OPERATION_QUEUE_TYPE_FIXED,
+                                                            (unsigned int) num);
   GNUNET_assert (GNUNET_OK ==
-                 GNUNET_CONFIGURATION_get_value_time (cfg, "TESTBED",
+                 GNUNET_CONFIGURATION_get_value_time (cfg,
+                                                      "TESTBED",
                                                       "OPERATION_TIMEOUT",
-                                                      (struct
-                                                       GNUNET_TIME_Relative *)
+                                                      (struct GNUNET_TIME_Relative *)
                                                       &GST_timeout));
   GNUNET_assert (GNUNET_OK ==
-                 GNUNET_CONFIGURATION_get_value_string (cfg, "testbed",
-                                                        "HOSTNAME", &hostname));
+                 GNUNET_CONFIGURATION_get_value_string (cfg,
+                                                        "testbed",
+                                                        "HOSTNAME",
+                                                        &hostname));
   GST_config = GNUNET_CONFIGURATION_dup (cfg);
-  GNUNET_SERVER_add_handlers (server, message_handlers);
-  GNUNET_SERVER_disconnect_notify (server, &client_disconnect_cb, NULL);
-  GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL);
+  GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
+                                 NULL);
   LOG_DEBUG ("Testbed startup complete\n");
   GST_stats_init (GST_config);
   GST_barriers_init (GST_config);
@@ -943,16 +895,84 @@ testbed_run (void *cls, struct GNUNET_SERVER_Handle *server,
 
 
 /**
- * The starting point of execution
- */
-int
-main (int argc, char *const *argv)
-{
-  return (GNUNET_OK ==
-          GNUNET_SERVICE_run (argc, argv,
-                             "testbed",
-                             GNUNET_SERVICE_OPTION_NONE,
-                              &testbed_run, NULL)) ? 0 : 1;
-}
+ * Define "main" method using service macro.
+ */
+GNUNET_SERVICE_MAIN
+("testbed",
+ GNUNET_SERVICE_OPTION_NONE,
+ &testbed_run,
+ &client_connect_cb,
+ &client_disconnect_cb,
+ NULL,
+ GNUNET_MQ_hd_var_size (init,
+                        GNUNET_MESSAGE_TYPE_TESTBED_INIT,
+                        struct GNUNET_TESTBED_InitMessage,
+                        NULL),
+ GNUNET_MQ_hd_var_size (add_host,
+                        GNUNET_MESSAGE_TYPE_TESTBED_ADD_HOST,
+                        struct GNUNET_TESTBED_AddHostMessage,
+                        NULL),
+ GNUNET_MQ_hd_fixed_size (slave_get_config,
+                          GNUNET_MESSAGE_TYPE_TESTBED_GET_SLAVE_CONFIGURATION,
+                          struct GNUNET_TESTBED_SlaveGetConfigurationMessage,
+                          NULL),
+ GNUNET_MQ_hd_fixed_size (link_controllers,
+                          GNUNET_MESSAGE_TYPE_TESTBED_LINK_CONTROLLERS,
+                          struct GNUNET_TESTBED_ControllerLinkRequest,
+                          NULL),
+ GNUNET_MQ_hd_var_size (remote_overlay_connect,
+                        GNUNET_MESSAGE_TYPE_TESTBED_REMOTE_OVERLAY_CONNECT,
+                        struct GNUNET_TESTBED_RemoteOverlayConnectMessage,
+                        NULL),
+ GNUNET_MQ_hd_fixed_size (overlay_connect,
+                          GNUNET_MESSAGE_TYPE_TESTBED_OVERLAY_CONNECT,
+                          struct GNUNET_TESTBED_OverlayConnectMessage,
+                          NULL),
+ GNUNET_MQ_hd_var_size (peer_create,
+                        GNUNET_MESSAGE_TYPE_TESTBED_CREATE_PEER,
+                        struct GNUNET_TESTBED_PeerCreateMessage,
+                        NULL),
+ GNUNET_MQ_hd_fixed_size (peer_destroy,
+                          GNUNET_MESSAGE_TYPE_TESTBED_DESTROY_PEER,
+                          struct GNUNET_TESTBED_PeerDestroyMessage,
+                          NULL),
+ GNUNET_MQ_hd_fixed_size (peer_start,
+                          GNUNET_MESSAGE_TYPE_TESTBED_START_PEER,
+                          struct GNUNET_TESTBED_PeerStartMessage,
+                          NULL),
+ GNUNET_MQ_hd_fixed_size (peer_stop,
+                          GNUNET_MESSAGE_TYPE_TESTBED_STOP_PEER,
+                          struct GNUNET_TESTBED_PeerStopMessage,
+                          NULL),
+ GNUNET_MQ_hd_fixed_size (peer_get_config,
+                          GNUNET_MESSAGE_TYPE_TESTBED_GET_PEER_INFORMATION,
+                          struct GNUNET_TESTBED_PeerGetConfigurationMessage,
+                          NULL),
+ GNUNET_MQ_hd_var_size (manage_peer_service,
+                        GNUNET_MESSAGE_TYPE_TESTBED_MANAGE_PEER_SERVICE,
+                        struct GNUNET_TESTBED_ManagePeerServiceMessage,
+                        NULL),
+ GNUNET_MQ_hd_fixed_size (shutdown_peers,
+                          GNUNET_MESSAGE_TYPE_TESTBED_SHUTDOWN_PEERS,
+                          struct GNUNET_TESTBED_ShutdownPeersMessage,
+                          NULL),
+ GNUNET_MQ_hd_var_size (peer_reconfigure,
+                        GNUNET_MESSAGE_TYPE_TESTBED_RECONFIGURE_PEER,
+                        struct GNUNET_TESTBED_PeerReconfigureMessage,
+                        NULL),
+ GNUNET_MQ_hd_var_size (barrier_init,
+                        GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_INIT,
+                        struct GNUNET_TESTBED_BarrierInit,
+                        NULL),
+ GNUNET_MQ_hd_var_size (barrier_cancel,
+                        GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_CANCEL,
+                        struct GNUNET_TESTBED_BarrierCancel,
+                        NULL),
+ GNUNET_MQ_hd_var_size (barrier_status,
+                        GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS,
+                        struct GNUNET_TESTBED_BarrierStatusMsg,
+                        NULL),
+ GNUNET_MQ_handler_end ());
+
 
 /* end of gnunet-service-testbed.c */
index b19d3c516d0eb38f996c2479b77140239b252a92..6f797a066b18139944322ca588d595f840493dba 100644 (file)
@@ -96,7 +96,7 @@ struct ForwardedOperationContext
   /**
    * The client to which we have to reply
    */
-  struct GNUNET_SERVER_Client *client;
+  struct GNUNET_SERVICE_Client *client;
 
   /**
    * Closure pointer
@@ -161,7 +161,7 @@ struct LinkControllersContext
   /**
    * The client which initiated the link controller operation
    */
-  struct GNUNET_SERVER_Client *client;
+  struct GNUNET_SERVICE_Client *client;
 
   /**
    * The ID of the operation
@@ -174,7 +174,6 @@ struct LinkControllersContext
 /**
  * A peer
  */
-
 struct Peer
 {
 
@@ -255,7 +254,7 @@ struct Context
   /**
    * The client handle associated with this context
    */
-  struct GNUNET_SERVER_Client *client;
+  struct GNUNET_SERVICE_Client *client;
 
   /**
    * The network address of the master controller
@@ -296,6 +295,9 @@ struct SharedService
 };
 
 
+struct RegisteredHostContext;
+
+
 /**
  * Context information to used during operations which forward the overlay
  * connect message
@@ -312,6 +314,11 @@ struct ForwardedOverlayConnectContext
    */
   struct ForwardedOverlayConnectContext *prev;
 
+  /**
+   * Which host does this FOCC belong to?
+   */
+  struct RegisteredHostContext *rhc;
+
   /**
    * A copy of the original overlay connect message
    */
@@ -320,7 +327,7 @@ struct ForwardedOverlayConnectContext
   /**
    * The client handle
    */
-  struct GNUNET_SERVER_Client *client;
+  struct GNUNET_SERVICE_Client *client;
 
   /**
    * The id of the operation which created this context information
@@ -391,13 +398,13 @@ struct RegisteredHostContext
 
 
 /**
- * Context data for GNUNET_MESSAGE_TYPE_TESTBED_SHUTDOWN_PEERS handler
+ * Context data for #GNUNET_MESSAGE_TYPE_TESTBED_SHUTDOWN_PEERS handler
  */
 struct HandlerContext_ShutdownPeers
 {
   /**
    * The number of slave we expect to hear from since we forwarded the
-   * GNUNET_MESSAGE_TYPE_TESTBED_SHUTDOWN_PEERS message to them
+   * #GNUNET_MESSAGE_TYPE_TESTBED_SHUTDOWN_PEERS message to them
    */
   unsigned int nslaves;
 
@@ -506,17 +513,6 @@ extern char *GST_stats_dir;
   } while (0)
 
 
-/**
- * Queues a message in send queue for sending to the service
- *
- * @param client the client to whom the queued message has to be sent
- * @param msg the message to queue
- */
-void
-GST_queue_message (struct GNUNET_SERVER_Client *client,
-                   struct GNUNET_MessageHeader *msg);
-
-
 /**
  * Function to destroy a peer
  *
@@ -530,7 +526,7 @@ GST_destroy_peer (struct Peer *peer);
  * Stops and destroys all peers
  */
 void
-GST_destroy_peers ();
+GST_destroy_peers (void);
 
 
 /**
@@ -546,15 +542,14 @@ GST_find_dest_route (uint32_t host_id);
 
 
 /**
- * Handler for GNUNET_MESSAGE_TYPE_TESTBED_OLCONNECT messages
+ * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_OVERLAY_CONNECT 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_overlay_connect (void *cls, struct GNUNET_SERVER_Client *client,
-                            const struct GNUNET_MessageHeader *message);
+handle_overlay_connect (void *cls,
+                        const struct GNUNET_TESTBED_OverlayConnectMessage *msg);
 
 
 /**
@@ -597,7 +592,7 @@ GST_forwarded_operation_timeout (void *cls);
  * Clears the forwarded operations queue
  */
 void
-GST_clear_fopcq ();
+GST_clear_fopcq (void);
 
 
 /**
@@ -608,8 +603,27 @@ GST_clear_fopcq ();
  * @param emsg the error message; can be NULL
  */
 void
-GST_send_operation_fail_msg (struct GNUNET_SERVER_Client *client,
-                             uint64_t operation_id, const char *emsg);
+GST_send_operation_fail_msg (struct GNUNET_SERVICE_Client *client,
+                             uint64_t operation_id,
+                             const char *emsg);
+
+
+/**
+ * Notify OC subsystem that @a client disconnected.
+ *
+ * @param client the client that disconnected
+ */
+void
+GST_notify_client_disconnect_oc (struct GNUNET_SERVICE_Client *client);
+
+
+/**
+ * Notify peers subsystem that @a client disconnected.
+ *
+ * @param client the client that disconnected
+ */
+void
+GST_notify_client_disconnect_peers (struct GNUNET_SERVICE_Client *client);
 
 
 /**
@@ -619,140 +633,180 @@ GST_send_operation_fail_msg (struct GNUNET_SERVER_Client *client,
  * @param operation_id the id of the operation which was successful
  */
 void
-GST_send_operation_success_msg (struct GNUNET_SERVER_Client *client,
+GST_send_operation_success_msg (struct GNUNET_SERVICE_Client *client,
                                 uint64_t operation_id);
 
 
 /**
- * Handler for GNUNET_MESSAGE_TYPE_TESTBED_REQUESTCONNECT messages
+ * Check #GNUNET_MESSAGE_TYPE_TESTBED_REMOTE_OVERLAY_CONNECT 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_remote_overlay_connect (void *cls,
+                              const struct GNUNET_TESTBED_RemoteOverlayConnectMessage *msg);
+
+
+/**
+ * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_REMOTE_OVERLAY_CONNECT messages
+ *
+ * @param cls identification of the client
+ * @param msg the actual message
  */
 void
-GST_handle_remote_overlay_connect (void *cls,
-                                   struct GNUNET_SERVER_Client *client,
-                                   const struct GNUNET_MessageHeader *message);
+handle_remote_overlay_connect (void *cls,
+                               const struct GNUNET_TESTBED_RemoteOverlayConnectMessage *msg);
+
+
+/**
+ * Check #GNUNET_MESSAGE_TYPE_TESTBED_CREATEPEER messages
+ *
+ * @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);
 
 
 /**
- * Handler for GNUNET_MESSAGE_TYPE_TESTBED_CREATEPEER messages
+ * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_CREATEPEER messages
  *
- * @param cls NULL
- * @param client identification of the client
+ * @param cls identification of the client
  * @param message 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);
 
 
 /**
- * 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);
 
 
 /**
- * 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_start (void *cls, struct GNUNET_SERVER_Client *client,
-                       const struct GNUNET_MessageHeader *message);
+handle_peer_start (void *cls,
+                   const struct GNUNET_TESTBED_PeerStartMessage *msg);
 
 
 /**
- * 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 cls identification of the client
  * @param message 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);
 
 
 /**
- * Handler for GNUNET_MESSAGE_TYPE_TESTBED_GETPEERCONFIG messages
+ * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_GETPEERCONFIG 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);
 
 
 /**
- * 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);
 
 
 /**
- * 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
+ */
+int
+check_manage_peer_service (void *cls,
+                           const struct GNUNET_TESTBED_ManagePeerServiceMessage *msg);
+
+
+/**
+ * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_MANAGE_PEER_SERVICE message
+ *
+ * @param cls identification of client
+ * @param msg the actual message
  */
 void
-GST_handle_manage_peer_service (void *cls, struct GNUNET_SERVER_Client *client,
-                                const struct GNUNET_MessageHeader *message);
+handle_manage_peer_service (void *cls,
+                            const struct GNUNET_TESTBED_ManagePeerServiceMessage *msg);
+
+
 
 
 /**
- * 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);
+
+
+/**
+ * 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);
 
 
 /**
  * Frees the ManageServiceContext queue
  */
 void
-GST_free_mctxq ();
+GST_free_mctxq (void);
 
 
 /**
  * Cleans up the queue used for forwarding link controllers requests
  */
 void
-GST_free_lcfq ();
+GST_free_lcf (void);
 
 
 /**
  * Cleans up the route list
  */
 void
-GST_route_list_clear ();
+GST_route_list_clear (void);
 
 
 /**
@@ -777,21 +831,21 @@ GST_cleanup_focc (struct ForwardedOverlayConnectContext *focc);
  * Clears all pending overlay connect contexts in queue
  */
 void
-GST_free_occq ();
+GST_free_occq (void);
 
 
 /**
  * Clears all pending remote overlay connect contexts in queue
  */
 void
-GST_free_roccq ();
+GST_free_roccq (void);
 
 
 /**
  * Cleans up the Peer reconfigure context list
  */
 void
-GST_free_prcq ();
+GST_free_prcq (void);
 
 
 /**
@@ -807,7 +861,7 @@ GST_cache_init (unsigned int size);
  * Clear cache
  */
 void
-GST_cache_clear ();
+GST_cache_clear (void);
 
 
 /**
@@ -845,6 +899,6 @@ GST_stats_init (const struct GNUNET_CONFIGURATION_Handle *cfg);
  * Shutdown the status calls module.
  */
 void
-GST_stats_destroy ();
+GST_stats_destroy (void);
 
 /* End of gnunet-service-testbed.h */
index c3ae82ed8d18a89a9d6ee2f3cb15764e5f0af079..831bc3c6da217b62c2b2cb133117e566bb2bdce5 100644 (file)
 struct Barrier;
 
 
-/**
- * Message queue for transmitting messages
- */
-struct MessageQueue
-{
-  /**
-   * next pointer for DLL
-   */
-  struct MessageQueue *next;
-
-  /**
-   * prev pointer for DLL
-   */
-  struct MessageQueue *prev;
-
-  /**
-   * The message to be sent
-   */
-  struct GNUNET_MessageHeader *msg;
-};
-
-
 /**
  * Context to be associated with each client
  */
@@ -105,22 +83,8 @@ struct ClientCtx
   /**
    * The client handle
    */
-  struct GNUNET_SERVER_Client *client;
-
-  /**
-   * the transmission handle
-   */
-  struct GNUNET_SERVER_TransmitHandle *tx;
+  struct GNUNET_SERVICE_Client *client;
 
-  /**
-   * message queue head
-   */
-  struct MessageQueue *mq_head;
-
-  /**
-   * message queue tail
-   */
-  struct MessageQueue *mq_tail;
 };
 
 
@@ -169,7 +133,7 @@ struct Barrier
   /**
    * The client handle to the master controller
    */
-  struct GNUNET_SERVER_Client *mc;
+  struct GNUNET_SERVICE_Client *mc;
 
   /**
    * The name of the barrier
@@ -199,7 +163,7 @@ struct Barrier
   /**
    * Identifier for the timeout task
    */
-  struct GNUNET_SCHEDULER_Task * tout_task;
+  struct GNUNET_SCHEDULER_Task *tout_task;
 
   /**
    * The status of this barrier
@@ -247,102 +211,7 @@ static struct GNUNET_CONTAINER_MultiHashMap *barrier_map;
 /**
  * Service context
  */
-static struct GNUNET_SERVICE_Context *ctx;
-
-
-/**
- * Function called to notify a client about the connection
- * begin ready to queue more data.  "buf" will be
- * NULL and "size" zero if the connection was closed for
- * writing in the meantime.
- *
- * @param cls client context
- * @param size number of bytes available in buf
- * @param buf where the callee should write the message
- * @return number of bytes written to buf
- */
-static size_t
-transmit_ready_cb (void *cls, size_t size, void *buf)
-{
-  struct ClientCtx *ctx = cls;
-  struct GNUNET_SERVER_Client *client = ctx->client;
-  struct MessageQueue *mq;
-  struct GNUNET_MessageHeader *msg;
-  size_t wrote;
-
-  ctx->tx = NULL;
-  if ((0 == size) || (NULL == buf))
-  {
-    GNUNET_assert (NULL != ctx->client);
-    GNUNET_SERVER_client_drop (ctx->client);
-    ctx->client = NULL;
-    return 0;
-  }
-  mq = ctx->mq_head;
-  msg = mq->msg;
-  wrote = ntohs (msg->size);
-  GNUNET_assert (size >= wrote);
-  GNUNET_memcpy (buf, msg, wrote);
-  GNUNET_CONTAINER_DLL_remove (ctx->mq_head, ctx->mq_tail, mq);
-  GNUNET_free (mq->msg);
-  GNUNET_free (mq);
-  if (NULL != (mq = ctx->mq_head))
-    ctx->tx = GNUNET_SERVER_notify_transmit_ready (client, ntohs (msg->size),
-                                                  MESSAGE_SEND_TIMEOUT (30),
-                                                  &transmit_ready_cb, ctx);
-  return wrote;
-}
-
-
-/**
- * Queue a message into a clients message queue
- *
- * @param ctx the context associated with the client
- * @param msg the message to queue.  Will be consumed
- */
-static void
-queue_message (struct ClientCtx *ctx, struct GNUNET_MessageHeader *msg)
-{
-  struct MessageQueue *mq;
-  struct GNUNET_SERVER_Client *client = ctx->client;
-
-  mq = GNUNET_new (struct MessageQueue);
-  mq->msg = msg;
-  LOG_DEBUG ("Queueing message of type %u, size %u for sending\n",
-             ntohs (msg->type), ntohs (msg->size));
-  GNUNET_CONTAINER_DLL_insert_tail (ctx->mq_head, ctx->mq_tail, mq);
-  if (NULL == ctx->tx)
-   ctx->tx = GNUNET_SERVER_notify_transmit_ready (client, ntohs (msg->size),
-                                                  MESSAGE_SEND_TIMEOUT (30),
-                                                  &transmit_ready_cb, ctx);
-}
-
-
-/**
- * Function to cleanup client context data structure
- *
- * @param ctx the client context data structure
- */
-static void
-cleanup_clientctx (struct ClientCtx *ctx)
-{
-  struct MessageQueue *mq;
-
-  if (NULL != ctx->client)
-  {
-    GNUNET_SERVER_client_set_user_context_ (ctx->client, NULL, 0);
-    GNUNET_SERVER_client_drop (ctx->client);
-  }
-  if (NULL != ctx->tx)
-    GNUNET_SERVER_notify_transmit_ready_cancel (ctx->tx);
-  if (NULL != (mq = ctx->mq_head))
-  {
-    GNUNET_CONTAINER_DLL_remove (ctx->mq_head, ctx->mq_tail, mq);
-    GNUNET_free (mq->msg);
-    GNUNET_free (mq);
-  }
-  GNUNET_free (ctx);
-}
+static struct GNUNET_SERVICE_Handle *ctx;
 
 
 /**
@@ -356,16 +225,18 @@ remove_barrier (struct Barrier *barrier)
 {
   struct ClientCtx *ctx;
 
-  GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (barrier_map,
-                                                                    &barrier->hash,
-                                                                    barrier));
+  GNUNET_assert (GNUNET_YES ==
+                 GNUNET_CONTAINER_multihashmap_remove (barrier_map,
+                                                       &barrier->hash,
+                                                       barrier));
   while (NULL != (ctx = barrier->head))
   {
-    GNUNET_CONTAINER_DLL_remove (barrier->head, barrier->tail, ctx);
-    cleanup_clientctx (ctx);
+    GNUNET_CONTAINER_DLL_remove (barrier->head,
+                                 barrier->tail,
+                                 ctx);
+    GNUNET_free (ctx);
   }
   GNUNET_free (barrier->name);
-  GNUNET_SERVER_client_drop (barrier->mc);
   GNUNET_free (barrier);
 }
 
@@ -383,7 +254,9 @@ cancel_wrappers (struct Barrier *barrier)
   while (NULL != (wrapper = barrier->whead))
   {
     GNUNET_TESTBED_barrier_cancel (wrapper->hbarrier);
-    GNUNET_CONTAINER_DLL_remove (barrier->whead, barrier->wtail, wrapper);
+    GNUNET_CONTAINER_DLL_remove (barrier->whead,
+                                 barrier->wtail,
+                                 wrapper);
     GNUNET_free (wrapper);
   }
 }
@@ -399,29 +272,33 @@ cancel_wrappers (struct Barrier *barrier)
  *   status=GNUNET_TESTBED_BARRIERSTATUS_ERROR
  */
 static void
-send_client_status_msg (struct GNUNET_SERVER_Client *client,
+send_client_status_msg (struct GNUNET_SERVICE_Client *client,
                         const char *name,
                         enum GNUNET_TESTBED_BarrierStatus status,
                         const char *emsg)
 {
+  struct GNUNET_MQ_Envelope *env;
   struct GNUNET_TESTBED_BarrierStatusMsg *msg;
   size_t name_len;
-  uint16_t msize;
-
-  GNUNET_assert ((NULL == emsg) || (GNUNET_TESTBED_BARRIERSTATUS_ERROR == status));
-  name_len = strlen (name);
-  msize = sizeof (struct GNUNET_TESTBED_BarrierStatusMsg)
-      + (name_len + 1)
-      + ((NULL == emsg) ? 0 : (strlen (emsg) + 1));
-  msg = GNUNET_malloc (msize);
-  msg->header.size = htons (msize);
-  msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS);
+  size_t err_len;
+
+  GNUNET_assert ( (NULL == emsg) ||
+                  (GNUNET_TESTBED_BARRIERSTATUS_ERROR == status) );
+  name_len = strlen (name) + 1;
+  err_len = ((NULL == emsg) ? 0 : (strlen (emsg) + 1));
+  env = GNUNET_MQ_msg_extra (msg,
+                             name_len + err_len,
+                             GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS);
   msg->status = htons (status);
-  msg->name_len = htons ((uint16_t) name_len);
-  GNUNET_memcpy (msg->data, name, name_len);
-  if (NULL != emsg)
-    GNUNET_memcpy (msg->data + name_len + 1, emsg, strlen (emsg));
-  GST_queue_message (client, &msg->header);
+  msg->name_len = htons ((uint16_t) name_len - 1);
+  GNUNET_memcpy (msg->data,
+                 name,
+                 name_len);
+  GNUNET_memcpy (msg->data + name_len,
+                 emsg,
+                 err_len);
+  GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
+                  env);
 }
 
 
@@ -433,82 +310,119 @@ send_client_status_msg (struct GNUNET_SERVER_Client *client,
  *   status=GNUNET_TESTBED_BARRIERSTATUS_ERROR
  */
 static void
-send_barrier_status_msg (struct Barrier *barrier, const char *emsg)
+send_barrier_status_msg (struct Barrier *barrier,
+                         const char *emsg)
 {
   GNUNET_assert (0 != barrier->status);
-  send_client_status_msg (barrier->mc, barrier->name, barrier->status, emsg);
+  send_client_status_msg (barrier->mc,
+                          barrier->name,
+                          barrier->status,
+                          emsg);
 }
 
 
 /**
- * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_WAIT messages.  This
+ * Check #GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_WAIT messages.
+ *
+ * @param cls identification of the client
+ * @param message the actual message
+ */
+static int
+check_barrier_wait (void *cls,
+                     const struct GNUNET_TESTBED_BarrierWait *msg)
+{
+  return GNUNET_OK; /* always well-formed */
+}
+
+
+/**
+ * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_WAIT messages.  This
  * message should come from peers or a shared helper service using the
  * testbed-barrier client API (@see gnunet_testbed_barrier_service.h)
  *
  * This handler is queued in the main service and will handle the messages sent
  * either from the testbed driver or from a high level controller
  *
- * @param cls NULL
- * @param client identification of the client
+ * @param cls identification of the client
  * @param message the actual message
  */
 static void
-handle_barrier_wait (void *cls, struct GNUNET_SERVER_Client *client,
-                     const struct GNUNET_MessageHeader *message)
+handle_barrier_wait (void *cls,
+                     const struct GNUNET_TESTBED_BarrierWait *msg)
 {
-  const struct GNUNET_TESTBED_BarrierWait *msg;
+  struct ClientCtx *client_ctx = cls;
   struct Barrier *barrier;
   char *name;
-  struct ClientCtx *client_ctx;
   struct GNUNET_HashCode key;
   size_t name_len;
   uint16_t msize;
 
-  msize = ntohs (message->size);
-  if (msize <= sizeof (struct GNUNET_TESTBED_BarrierWait))
-  {
-    GNUNET_break_op (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
-    return;
-  }
+  msize = ntohs (msg->header.size);
   if (NULL == barrier_map)
   {
     GNUNET_break (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+    GNUNET_SERVICE_client_drop (client_ctx->client);
     return;
   }
-  msg = (const struct GNUNET_TESTBED_BarrierWait *) message;
   name_len = msize - sizeof (struct GNUNET_TESTBED_BarrierWait);
   name = GNUNET_malloc (name_len + 1);
   name[name_len] = '\0';
-  GNUNET_memcpy (name, msg->name, name_len);
-  LOG_DEBUG ("Received BARRIER_WAIT for barrier `%s'\n", name);
-  GNUNET_CRYPTO_hash (name, name_len, &key);
+  GNUNET_memcpy (name,
+                 msg->name,
+                 name_len);
+  LOG_DEBUG ("Received BARRIER_WAIT for barrier `%s'\n",
+             name);
+  GNUNET_CRYPTO_hash (name,
+                      name_len,
+                      &key);
   GNUNET_free (name);
   if (NULL == (barrier = GNUNET_CONTAINER_multihashmap_get (barrier_map, &key)))
   {
     GNUNET_break (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+    GNUNET_SERVICE_client_drop (client_ctx->client);
     return;
   }
-  client_ctx = GNUNET_SERVER_client_get_user_context (client, struct ClientCtx);
-  if (NULL == client_ctx)
+  if (NULL != client_ctx->barrier)
   {
-    client_ctx = GNUNET_new (struct ClientCtx);
-    client_ctx->client = client;
-    GNUNET_SERVER_client_keep (client);
-    client_ctx->barrier = barrier;
-    GNUNET_CONTAINER_DLL_insert_tail (barrier->head, barrier->tail, client_ctx);
-    GNUNET_SERVER_client_set_user_context (client, client_ctx);
+    GNUNET_break (0);
+    GNUNET_SERVICE_client_drop (client_ctx->client);
+    return;
   }
+  client_ctx->barrier = barrier;
+  GNUNET_CONTAINER_DLL_insert_tail (barrier->head,
+                                    barrier->tail,
+                                    client_ctx);
   barrier->nreached++;
-  if ((barrier->num_wbarriers_reached == barrier->num_wbarriers)
-        && (LOCAL_QUORUM_REACHED (barrier)))
+  if ( (barrier->num_wbarriers_reached == barrier->num_wbarriers) &&
+       (LOCAL_QUORUM_REACHED (barrier)) )
   {
     barrier->status = GNUNET_TESTBED_BARRIERSTATUS_CROSSED;
-    send_barrier_status_msg (barrier, NULL);
+    send_barrier_status_msg (barrier,
+                             NULL);
   }
-  GNUNET_SERVER_receive_done (client, GNUNET_OK);
+  GNUNET_SERVICE_client_continue (client_ctx->client);
+}
+
+
+/**
+ * Function called when a client connects to the testbed-barrier service.
+ *
+ * @param cls NULL
+ * @param client the connecting client
+ * @param mq queue to talk to @a client
+ * @return our `struct ClientCtx`
+ */
+static void *
+connect_cb (void *cls,
+            struct GNUNET_SERVICE_Client *client,
+            struct GNUNET_MQ_Handle *mq)
+{
+  struct ClientCtx *client_ctx;
+
+  LOG_DEBUG ("Client connected to testbed-barrier service\n");
+  client_ctx = GNUNET_new (struct ClientCtx);
+  client_ctx->client = client;
+  return client_ctx;
 }
 
 
@@ -521,16 +435,22 @@ handle_barrier_wait (void *cls, struct GNUNET_SERVER_Client *client,
  *        for the last call when the server is destroyed
  */
 static void
-disconnect_cb (void *cls, struct GNUNET_SERVER_Client *client)
+disconnect_cb (void *cls,
+               struct GNUNET_SERVICE_Client *client,
+               void *app_ctx)
 {
-  struct ClientCtx *client_ctx;
+  struct ClientCtx *client_ctx = app_ctx;
+  struct Barrier *barrier = client_ctx->barrier;
 
-  if (NULL == client)
-    return;
-  client_ctx = GNUNET_SERVER_client_get_user_context (client, struct ClientCtx);
-  if (NULL == client_ctx)
-    return;
-  cleanup_clientctx (client_ctx);
+  if (NULL != barrier)
+  {
+    GNUNET_CONTAINER_DLL_remove (barrier->head,
+                                 barrier->tail,
+                                 client_ctx);
+    client_ctx->barrier = NULL;
+  }
+  GNUNET_free (client_ctx);
+  LOG_DEBUG ("Client disconnected from testbed-barrier service\n");
 }
 
 
@@ -542,18 +462,23 @@ disconnect_cb (void *cls, struct GNUNET_SERVER_Client *client)
 void
 GST_barriers_init (struct GNUNET_CONFIGURATION_Handle *cfg)
 {
-  static const struct GNUNET_SERVER_MessageHandler message_handlers[] = {
-    {&handle_barrier_wait, NULL, GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_WAIT, 0},
-    {NULL, NULL, 0, 0}
+  struct GNUNET_MQ_MessageHandler message_handlers[] = {
+    GNUNET_MQ_hd_var_size (barrier_wait,
+                           GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_WAIT,
+                           struct GNUNET_TESTBED_BarrierWait,
+                           NULL),
+    GNUNET_MQ_handler_end ()
   };
-  struct GNUNET_SERVER_Handle *srv;
-
-  barrier_map = GNUNET_CONTAINER_multihashmap_create (3, GNUNET_YES);
-  ctx = GNUNET_SERVICE_start ("testbed-barrier", cfg,
-                              GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN);
-  srv = GNUNET_SERVICE_get_server (ctx);
-  GNUNET_SERVER_add_handlers (srv, message_handlers);
-  GNUNET_SERVER_disconnect_notify (srv, &disconnect_cb, NULL);
+
+  LOG_DEBUG ("Launching testbed-barrier service\n");
+  barrier_map = GNUNET_CONTAINER_multihashmap_create (3,
+                                                      GNUNET_YES);
+  ctx = GNUNET_SERVICE_starT ("testbed-barrier",
+                              cfg,
+                              &connect_cb,
+                              &disconnect_cb,
+                              NULL,
+                              message_handlers);
 }
 
 
@@ -594,7 +519,7 @@ GST_barriers_destroy ()
                                                         NULL));
   GNUNET_CONTAINER_multihashmap_destroy (barrier_map);
   GNUNET_assert (NULL != ctx);
-  GNUNET_SERVICE_stop (ctx);
+  GNUNET_SERVICE_stoP (ctx);
 }
 
 
@@ -606,13 +531,14 @@ GST_barriers_destroy ()
  * @param cls the closure given to GNUNET_TESTBED_barrier_init()
  * @param name the name of the barrier
  * @param b_ the barrier handle
- * @param status status of the barrier; GNUNET_OK if the barrier is crossed;
- *   GNUNET_SYSERR upon error
- * @param emsg if the status were to be GNUNET_SYSERR, this parameter has the
+ * @param status status of the barrier; #GNUNET_OK if the barrier is crossed;
+ *   #GNUNET_SYSERR upon error
+ * @param emsg if the status were to be #GNUNET_SYSERR, this parameter has the
  *   error messsage
  */
 static void
-wbarrier_status_cb (void *cls, const char *name,
+wbarrier_status_cb (void *cls,
+                    const char *name,
                     struct GNUNET_TESTBED_Barrier *b_,
                     enum GNUNET_TESTBED_BarrierStatus status,
                     const char *emsg)
@@ -622,14 +548,17 @@ wbarrier_status_cb (void *cls, const char *name,
 
   GNUNET_assert (b_ == wrapper->hbarrier);
   wrapper->hbarrier = NULL;
-  GNUNET_CONTAINER_DLL_remove (barrier->whead, barrier->wtail, wrapper);
+  GNUNET_CONTAINER_DLL_remove (barrier->whead,
+                               barrier->wtail,
+                               wrapper);
   GNUNET_free (wrapper);
   switch (status)
   {
   case GNUNET_TESTBED_BARRIERSTATUS_ERROR:
     LOG (GNUNET_ERROR_TYPE_ERROR,
          "Initialising barrier `%s' failed at a sub-controller: %s\n",
-         barrier->name, (NULL != emsg) ? emsg : "NULL");
+         barrier->name,
+         (NULL != emsg) ? emsg : "NULL");
     cancel_wrappers (barrier);
     if (NULL == emsg)
       emsg = "Initialisation failed at a sub-controller";
@@ -686,23 +615,38 @@ fwd_tout_barrier_init (void *cls)
 }
 
 
+
+/**
+ * Check #GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_INIT messages.
+ *
+ * @param cls identification of the client
+ * @param msg the actual message
+ * @return #GNUNET_OK if @a msg is well-formed
+ */
+int
+check_barrier_init (void *cls,
+                    const struct GNUNET_TESTBED_BarrierInit *msg)
+{
+  return GNUNET_OK; /* always well-formed */
+}
+
+
 /**
- * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_INIT messages.  This
+ * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_INIT messages.  This
  * message should always come from a parent controller or the testbed API if we
  * are the root controller.
  *
  * This handler is queued in the main service and will handle the messages sent
  * either from the testbed driver or from a high level controller
  *
- * @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_barrier_init (void *cls, struct GNUNET_SERVER_Client *client,
-                         const struct GNUNET_MessageHeader *message)
+handle_barrier_init (void *cls,
+                     const struct GNUNET_TESTBED_BarrierInit *msg)
 {
-  const struct GNUNET_TESTBED_BarrierInit *msg;
+  struct GNUNET_SERVICE_Client *client = cls;
   char *name;
   struct Barrier *barrier;
   struct Slave *slave;
@@ -715,49 +659,45 @@ GST_handle_barrier_init (void *cls, struct GNUNET_SERVER_Client *client,
   if (NULL == GST_context)
   {
     GNUNET_break_op (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+    GNUNET_SERVICE_client_drop (client);
     return;
   }
   if (client != GST_context->client)
   {
     GNUNET_break_op (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+    GNUNET_SERVICE_client_drop (client);
     return;
   }
-  msize = ntohs (message->size);
-  if (msize <= sizeof (struct GNUNET_TESTBED_BarrierInit))
-  {
-    GNUNET_break_op (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
-    return;
-  }
-  msg = (const struct GNUNET_TESTBED_BarrierInit *) message;
+  msize = ntohs (msg->header.size);
   name_len = (size_t) msize - sizeof (struct GNUNET_TESTBED_BarrierInit);
   name = GNUNET_malloc (name_len + 1);
   GNUNET_memcpy (name, msg->name, name_len);
   GNUNET_CRYPTO_hash (name, name_len, &hash);
-  LOG_DEBUG ("Received BARRIER_INIT for barrier `%s'\n", name);
-  if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (barrier_map, &hash))
+  LOG_DEBUG ("Received BARRIER_INIT for barrier `%s'\n",
+             name);
+  if (GNUNET_YES ==
+      GNUNET_CONTAINER_multihashmap_contains (barrier_map,
+                                              &hash))
   {
-
-    send_client_status_msg (client, name, GNUNET_TESTBED_BARRIERSTATUS_ERROR,
+    send_client_status_msg (client,
+                            name,
+                            GNUNET_TESTBED_BARRIERSTATUS_ERROR,
                             "A barrier with the same name already exists");
     GNUNET_free (name);
-    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    GNUNET_SERVICE_client_continue (client);
     return;
   }
   barrier = GNUNET_new (struct Barrier);
-  GNUNET_memcpy (&barrier->hash, &hash, sizeof (struct GNUNET_HashCode));
+  barrier->hash = hash;
   barrier->quorum = msg->quorum;
   barrier->name = name;
   barrier->mc = client;
-  GNUNET_SERVER_client_keep (client);
   GNUNET_assert (GNUNET_OK ==
                  GNUNET_CONTAINER_multihashmap_put (barrier_map,
                                                     &barrier->hash,
                                                     barrier,
                                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST));
-  GNUNET_SERVER_receive_done (client, GNUNET_OK);
+  GNUNET_SERVICE_client_continue (client);
   /* Propagate barrier init to subcontrollers */
   for (cnt = 0; cnt < GST_slave_list_size; cnt++)
   {
@@ -770,7 +710,9 @@ GST_handle_barrier_init (void *cls, struct GNUNET_SERVER_Client *client,
     }
     wrapper = GNUNET_new (struct WBarrier);
     wrapper->barrier = barrier;
-    GNUNET_CONTAINER_DLL_insert_tail (barrier->whead, barrier->wtail, wrapper);
+    GNUNET_CONTAINER_DLL_insert_tail (barrier->whead,
+                                      barrier->wtail,
+                                      wrapper);
     wrapper->hbarrier = GNUNET_TESTBED_barrier_init_ (slave->controller,
                                                       barrier->name,
                                                       barrier->quorum,
@@ -792,22 +734,36 @@ GST_handle_barrier_init (void *cls, struct GNUNET_SERVER_Client *client,
 
 
 /**
- * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_CANCEL messages.  This
+ * Check #GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_CANCEL messages.
+ *
+ * @param cls identification of the client
+ * @param msg the actual message
+ * @return #GNUNET_OK if @a msg is well-formed
+ */
+int
+check_barrier_cancel (void *cls,
+                      const struct GNUNET_TESTBED_BarrierCancel *msg)
+{
+  return GNUNET_OK; /* all are well-formed */
+}
+
+
+/**
+ * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_CANCEL messages.  This
  * message should always come from a parent controller or the testbed API if we
  * are the root controller.
  *
  * This handler is queued in the main service and will handle the messages sent
  * either from the testbed driver or from a high level controller
  *
- * @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_barrier_cancel (void *cls, struct GNUNET_SERVER_Client *client,
-                           const struct GNUNET_MessageHeader *message)
+handle_barrier_cancel (void *cls,
+                       const struct GNUNET_TESTBED_BarrierCancel *msg)
 {
-  const struct GNUNET_TESTBED_BarrierCancel *msg;
+  struct GNUNET_SERVICE_Client *client = cls;
   char *name;
   struct Barrier *barrier;
   struct GNUNET_HashCode hash;
@@ -817,119 +773,140 @@ GST_handle_barrier_cancel (void *cls, struct GNUNET_SERVER_Client *client,
   if (NULL == GST_context)
   {
     GNUNET_break_op (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+    GNUNET_SERVICE_client_drop (client);
     return;
   }
   if (client != GST_context->client)
   {
     GNUNET_break_op (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+    GNUNET_SERVICE_client_drop (client);
     return;
   }
-  msize = ntohs (message->size);
-  if (msize <= sizeof (struct GNUNET_TESTBED_BarrierCancel))
-  {
-    GNUNET_break_op (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
-    return;
-  }
-  msg = (const struct GNUNET_TESTBED_BarrierCancel *) message;
+  msize = ntohs (msg->header.size);
   name_len = msize - sizeof (struct GNUNET_TESTBED_BarrierCancel);
   name = GNUNET_malloc (name_len + 1);
-  GNUNET_memcpy (name, msg->name, name_len);
-  GNUNET_CRYPTO_hash (name, name_len, &hash);
-  if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (barrier_map, &hash))
+  GNUNET_memcpy (name,
+                 msg->name,
+                 name_len);
+  LOG_DEBUG ("Received BARRIER_CANCEL for barrier `%s'\n",
+             name);
+  GNUNET_CRYPTO_hash (name,
+                      name_len,
+                      &hash);
+  if (GNUNET_NO ==
+      GNUNET_CONTAINER_multihashmap_contains (barrier_map,
+                                              &hash))
   {
     GNUNET_break_op (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+    GNUNET_SERVICE_client_drop (client);
     return;
   }
-  barrier = GNUNET_CONTAINER_multihashmap_get (barrier_map, &hash);
+  barrier = GNUNET_CONTAINER_multihashmap_get (barrier_map,
+                                               &hash);
   GNUNET_assert (NULL != barrier);
   cancel_wrappers (barrier);
   remove_barrier (barrier);
-  GNUNET_SERVER_receive_done (client, GNUNET_OK);
+  GNUNET_SERVICE_client_continue (client);
 }
 
 
 /**
- * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS messages.
+ * Check #GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS messages.
+ *
+ * @param cls identification of the client
+ * @param msg the actual message
+ * @return #GNUNET_OK if @a msg is well-formed
+ */
+int
+check_barrier_status (void *cls,
+                      const struct GNUNET_TESTBED_BarrierStatusMsg *msg)
+{
+  uint16_t msize;
+  uint16_t name_len;
+  const char *name;
+  enum GNUNET_TESTBED_BarrierStatus status;
+
+  msize = ntohs (msg->header.size) - sizeof (*msg);
+  status = ntohs (msg->status);
+  if (GNUNET_TESTBED_BARRIERSTATUS_CROSSED != status)
+  {
+    GNUNET_break_op (0);        /* current we only expect BARRIER_CROSSED
+                                   status message this way */
+    return GNUNET_SYSERR;
+  }
+  name = msg->data;
+  name_len = ntohs (msg->name_len);
+  if ((name_len + 1) != msize)
+  {
+    GNUNET_break_op (0);
+    return GNUNET_SYSERR;
+  }
+  if ('\0' != name[name_len])
+  {
+    GNUNET_break_op (0);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+
+/**
+ * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS messages.
  * This handler is queued in the main service and will handle the messages sent
  * either from the testbed driver or from a high level controller
  *
- * @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_barrier_status (void *cls,
-                           struct GNUNET_SERVER_Client *client,
-                           const struct GNUNET_MessageHeader *message)
+handle_barrier_status (void *cls,
+                       const struct GNUNET_TESTBED_BarrierStatusMsg *msg)
 {
-  const struct GNUNET_TESTBED_BarrierStatusMsg *msg;
+  struct GNUNET_SERVICE_Client *client = cls;
   struct Barrier *barrier;
   struct ClientCtx *client_ctx;
   const char *name;
   struct GNUNET_HashCode key;
-  enum GNUNET_TESTBED_BarrierStatus status;
-  uint16_t msize;
   uint16_t name_len;
+  struct GNUNET_MQ_Envelope *env;
 
   if (NULL == GST_context)
   {
     GNUNET_break_op (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+    GNUNET_SERVICE_client_drop (client);
     return;
   }
   if (client != GST_context->client)
   {
     GNUNET_break_op (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
-    return;
-  }
-  msize = ntohs (message->size);
-  if (msize <= sizeof (struct GNUNET_TESTBED_BarrierStatusMsg))
-  {
-    GNUNET_break_op (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
-    return;
-  }
-  msg = (const struct GNUNET_TESTBED_BarrierStatusMsg *) message;
-  status = ntohs (msg->status);
-  if (GNUNET_TESTBED_BARRIERSTATUS_CROSSED != status)
-  {
-    GNUNET_break_op (0);        /* current we only expect BARRIER_CROSSED
-                                   status message this way */
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+    GNUNET_SERVICE_client_drop (client);
     return;
   }
   name = msg->data;
   name_len = ntohs (msg->name_len);
-  if ((sizeof (struct GNUNET_TESTBED_BarrierStatusMsg) + name_len + 1) != msize)
-  {
-    GNUNET_break_op (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
-    return;
-  }
-  if ('\0' != name[name_len])
-  {
-    GNUNET_break_op (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
-    return;
-  }
-  GNUNET_CRYPTO_hash (name, name_len, &key);
-  barrier = GNUNET_CONTAINER_multihashmap_get (barrier_map, &key);
+  LOG_DEBUG ("Received BARRIER_STATUS for barrier `%s'\n",
+             name);
+  GNUNET_CRYPTO_hash (name,
+                      name_len,
+                      &key);
+  barrier = GNUNET_CONTAINER_multihashmap_get (barrier_map,
+                                               &key);
   if (NULL == barrier)
   {
     GNUNET_break_op (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+    GNUNET_SERVICE_client_drop (client);
     return;
   }
-  GNUNET_SERVER_receive_done (client, GNUNET_OK);
+  GNUNET_SERVICE_client_continue (client);
   while (NULL != (client_ctx = barrier->head)) /* Notify peers */
   {
-    queue_message (client_ctx, GNUNET_copy_message (message));
-    GNUNET_CONTAINER_DLL_remove (barrier->head, barrier->tail, client_ctx);
+    env = GNUNET_MQ_msg_copy (&msg->header);
+    GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
+                    env);
+    GNUNET_CONTAINER_DLL_remove (barrier->head,
+                                 barrier->tail,
+                                 client_ctx);
+    client_ctx->barrier = NULL;
   }
 }
 
index ed5ba309bce837984d7bdbd16eb9f46511090929..2fc3222f8864829f3b15141b0e42a4518a70b28d 100644 (file)
@@ -40,55 +40,88 @@ GST_barriers_init (struct GNUNET_CONFIGURATION_Handle *cfg);
  * Function to stop the barrier service
  */
 void
-GST_barriers_destroy ();
+GST_barriers_destroy (void);
 
 
 /**
- * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_INIT messages.  This
+ * Check #GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_INIT messages.
+ *
+ * @param cls identification of the client
+ * @param msg the actual message
+ * @return #GNUNET_OK if @a msg is well-formed
+ */
+int
+check_barrier_init (void *cls,
+                    const struct GNUNET_TESTBED_BarrierInit *msg);
+
+
+/**
+ * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_INIT messages.  This
  * message should always come from a parent controller or the testbed API if we
  * are the root controller.
  *
  * This handler is queued in the main service and will handle the messages sent
  * either from the testbed driver or from a high level controller
  *
- * @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_barrier_init (void *cls, struct GNUNET_SERVER_Client *client,
-                         const struct GNUNET_MessageHeader *message);
+handle_barrier_init (void *cls,
+                     const struct GNUNET_TESTBED_BarrierInit *msg);
 
 
 /**
- * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_CANCEL messages.  This
+ * Check #GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_CANCEL messages.
+ *
+ * @param cls identification of the client
+ * @param msg the actual message
+ * @return #GNUNET_OK if @a msg is well-formed
+ */
+int
+check_barrier_cancel (void *cls,
+                      const struct GNUNET_TESTBED_BarrierCancel *msg);
+
+
+/**
+ * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_CANCEL messages.  This
  * message should always come from a parent controller or the testbed API if we
  * are the root controller.
  *
  * This handler is queued in the main service and will handle the messages sent
  * either from the testbed driver or from a high level controller
  *
- * @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_barrier_cancel (void *cls, struct GNUNET_SERVER_Client *client,
-                           const struct GNUNET_MessageHeader *message);
+handle_barrier_cancel (void *cls,
+                       const struct GNUNET_TESTBED_BarrierCancel *msg);
+
+
+/**
+ * Check #GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS messages.
+ *
+ * @param cls identification of the client
+ * @param msg the actual message
+ * @return #GNUNET_OK if @a msg is well-formed
+ */
+int
+check_barrier_status (void *cls,
+                      const struct GNUNET_TESTBED_BarrierStatusMsg *msg);
 
 
 /**
- * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS messages.
+ * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS messages.
  * This handler is queued in the main service and will handle the messages sent
  * either from the testbed driver or from a high level controller
  *
- * @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_barrier_status (void *cls, struct GNUNET_SERVER_Client *client,
-                           const struct GNUNET_MessageHeader *message);
+handle_barrier_status (void *cls,
+                       const struct GNUNET_TESTBED_BarrierStatusMsg *msg);
 
 #endif  /* GNUNET_SERVER_TESTBED_BARRIERS_H_ */
 
index b922a8da81db6d57f8058d9911c49a62ab8992f8..3447a3f344dcca7873dac60221a733320ce032aa 100644 (file)
@@ -74,6 +74,16 @@ enum LCFContextState
  */
 struct LCFContext
 {
+  /**
+   * The LCFContext
+   */
+  struct LCFContext *next;
+
+  /**
+   * The LCFContext
+   */
+  struct LCFContext *prev;
+
   /**
    * The gateway which will pass the link message to delegated host
    */
@@ -82,7 +92,7 @@ struct LCFContext
   /**
    * The client which has asked to perform this operation
    */
-  struct GNUNET_SERVER_Client *client;
+  struct GNUNET_SERVICE_Client *client;
 
   /**
    * Handle for operations which are forwarded while linking controllers
@@ -92,7 +102,7 @@ struct LCFContext
   /**
    * The timeout task
    */
-  struct GNUNET_SCHEDULER_Task * timeout_task;
+  struct GNUNET_SCHEDULER_Task *timeout_task;
 
   /**
    * The id of the operation which created this context
@@ -122,28 +132,6 @@ struct LCFContext
 };
 
 
-/**
- * Structure of a queue entry in LCFContext request queue
- */
-struct LCFContextQueue
-{
-  /**
-   * The LCFContext
-   */
-  struct LCFContext *lcf;
-
-  /**
-   * Head prt for DLL
-   */
-  struct LCFContextQueue *next;
-
-  /**
-   * Tail ptr for DLL
-   */
-  struct LCFContextQueue *prev;
-};
-
-
 /**
  * Notification context to be used to notify when connection to the neighbour's
  * controller is opened
@@ -260,12 +248,12 @@ struct NeighbourConnectCtxt
   /**
    * The client requesting the connection
    */
-  struct GNUNET_SERVER_Client *client;
+  struct GNUNET_SERVICE_Client *client;
 
   /**
    * Task to be run upon timeout
    */
-  struct GNUNET_SCHEDULER_Task * timeout_task;
+  struct GNUNET_SCHEDULER_Task *timeout_task;
 
   /**
    * The notification handle associated with the neighbour's connection request
@@ -305,14 +293,14 @@ unsigned int GST_slave_list_size;
 static struct Route **route_list;
 
 /**
- * The head for the LCF queue
+ * The LCF queue
  */
-static struct LCFContextQueue *lcfq_head;
+static struct LCFContext *lcf_head;
 
 /**
  * The tail for the LCF queue
  */
-static struct LCFContextQueue *lcfq_tail;
+static struct LCFContext *lcf_tail;
 
 /**
  * The lcf_task handle
@@ -334,13 +322,43 @@ static void
 slave_list_add (struct Slave *slave)
 {
   if (slave->host_id >= GST_slave_list_size)
-    GST_array_grow_large_enough (GST_slave_list, GST_slave_list_size,
+    GST_array_grow_large_enough (GST_slave_list,
+                                 GST_slave_list_size,
                                  slave->host_id);
   GNUNET_assert (NULL == GST_slave_list[slave->host_id]);
   GST_slave_list[slave->host_id] = slave;
 }
 
 
+/**
+ * Clean up all forwarded operation overlay context matching the
+ * client given in @a cls.
+ *
+ * @param cls a `struct GNUNET_SERVICE_Client *` to match
+ * @param key unused
+ * @param value the `struct RegisteredHostContext` to search for @a cls
+ * @return #GNUNET_OK (continue iterating)
+ */
+static int
+drop_client_entries (void *cls,
+                     const struct GNUNET_HashCode *key,
+                     void *value)
+{
+  struct GNUNET_SERVICE_Client *client = cls;
+  struct RegisteredHostContext *rhc = value;
+  struct ForwardedOverlayConnectContext *focc;
+  struct ForwardedOverlayConnectContext *foccn;
+
+  for (focc = rhc->focc_dll_head; NULL != focc; focc = foccn)
+  {
+    foccn = focc->next;
+    if (focc->client == client)
+      GST_cleanup_focc (focc);
+  }
+  return GNUNET_OK;
+}
+
+
 /**
  * Adds a route to the route list
  *
@@ -394,12 +412,12 @@ GST_route_list_clear ()
  * @param cls handle to the slave
  * @param key current key code
  * @param value value in the hash map
- * @return GNUNET_YES if we should continue to
- *         iterate,
- *         GNUNET_NO if not.
+ * @return #GNUNET_YES if we should continue to iterate,
+ *         #GNUNET_NO if not.
  */
 static int
-reghost_free_iterator (void *cls, const struct GNUNET_HashCode *key,
+reghost_free_iterator (void *cls,
+                       const struct GNUNET_HashCode *key,
                        void *value)
 {
   struct Slave *slave = cls;
@@ -410,10 +428,7 @@ reghost_free_iterator (void *cls, const struct GNUNET_HashCode *key,
                  GNUNET_CONTAINER_multihashmap_remove (slave->reghost_map, key,
                                                        value));
   while (NULL != (focc = rhc->focc_dll_head))
-  {
-    GNUNET_CONTAINER_DLL_remove (rhc->focc_dll_head, rhc->focc_dll_tail, focc);
     GST_cleanup_focc (focc);
-  }
   GNUNET_free (value);
   return GNUNET_YES;
 }
@@ -536,12 +551,12 @@ GST_find_dest_route (uint32_t host_id)
  *          NULL if cfg is set!
  */
 static void
-send_controller_link_response (struct GNUNET_SERVER_Client *client,
+send_controller_link_response (struct GNUNET_SERVICE_Client *client,
                                uint64_t operation_id,
-                               const struct GNUNET_CONFIGURATION_Handle
-                               *cfg,
+                               const struct GNUNET_CONFIGURATION_Handle *cfg,
                                const char *emsg)
 {
+  struct GNUNET_MQ_Envelope *env;
   struct GNUNET_TESTBED_ControllerLinkResponse *msg;
   char *xconfig;
   size_t config_size;
@@ -552,7 +567,7 @@ send_controller_link_response (struct GNUNET_SERVER_Client *client,
   xconfig = NULL;
   xconfig_size = 0;
   config_size = 0;
-  msize = sizeof (struct GNUNET_TESTBED_ControllerLinkResponse);
+  msize = 0;
   if (NULL != cfg)
   {
     xconfig = GNUNET_TESTBED_compress_cfg_ (cfg,
@@ -562,22 +577,26 @@ send_controller_link_response (struct GNUNET_SERVER_Client *client,
   }
   if (NULL != emsg)
     msize += strlen (emsg);
-  msg = GNUNET_malloc (msize);
-  msg->header.type = htons
-      (GNUNET_MESSAGE_TYPE_TESTBED_LINK_CONTROLLERS_RESULT);
-  msg->header.size = htons (msize);
+  env = GNUNET_MQ_msg_extra (msg,
+                             msize,
+                             GNUNET_MESSAGE_TYPE_TESTBED_LINK_CONTROLLERS_RESULT);
   if (NULL == emsg)
     msg->success = htons (GNUNET_YES);
   msg->operation_id = GNUNET_htonll (operation_id);
   msg->config_size = htons ((uint16_t) config_size);
   if (NULL != xconfig)
   {
-    GNUNET_memcpy (&msg[1], xconfig, xconfig_size);
+    GNUNET_memcpy (&msg[1],
+                   xconfig,
+                   xconfig_size);
     GNUNET_free (xconfig);
   }
   if (NULL != emsg)
-    GNUNET_memcpy (&msg[1], emsg, strlen (emsg));
-  GST_queue_message (client, &msg->header);
+    GNUNET_memcpy (&msg[1],
+                   emsg,
+                   strlen (emsg));
+  GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
+                  env);
 }
 
 
@@ -597,7 +616,8 @@ lcf_proc_task (void *cls);
  * @param emsg the error message; NULL if host registration is successful
  */
 static void
-lcf_proc_cc (void *cls, const char *emsg)
+lcf_proc_cc (void *cls,
+             const char *emsg)
 {
   struct LCFContext *lcf = cls;
 
@@ -622,10 +642,12 @@ lcf_proc_cc (void *cls, const char *emsg)
   return;
 
 registration_error:
-  LOG (GNUNET_ERROR_TYPE_WARNING, "Host registration failed with message: %s\n",
+  LOG (GNUNET_ERROR_TYPE_WARNING,
+       "Host registration failed with message: %s\n",
        emsg);
   lcf->state = FINISHED;
-  lcf_proc_task_id = GNUNET_SCHEDULER_add_now (&lcf_proc_task, lcf);
+  lcf_proc_task_id = GNUNET_SCHEDULER_add_now (&lcf_proc_task,
+                                               lcf);
 }
 
 
@@ -652,11 +674,13 @@ lcf_forwarded_operation_timeout (void *cls)
   //  GST_forwarded_operation_timeout (lcf->fopc, tc);
   LOG (GNUNET_ERROR_TYPE_WARNING,
        "A forwarded controller link operation has timed out\n");
-  send_controller_link_response (lcf->client, lcf->operation_id, NULL,
-                                 "A forwarded controller link operation has "
-                                 "timed out\n");
+  send_controller_link_response (lcf->client,
+                                 lcf->operation_id,
+                                 NULL,
+                                 "A forwarded controller link operation has timed out\n");
   GNUNET_assert (NULL == lcf_proc_task_id);
-  lcf_proc_task_id = GNUNET_SCHEDULER_add_now (&lcf_proc_task, lcf);
+  lcf_proc_task_id = GNUNET_SCHEDULER_add_now (&lcf_proc_task,
+                                               lcf);
 }
 
 
@@ -669,7 +693,6 @@ static void
 lcf_proc_task (void *cls)
 {
   struct LCFContext *lcf = cls;
-  struct LCFContextQueue *lcfq;
 
   lcf_proc_task_id = NULL;
   switch (lcf->state)
@@ -710,22 +733,21 @@ lcf_proc_task (void *cls)
                                               GST_host_list[lcf->slave_host_id],
                                               lcf->is_subordinate);
     lcf->timeout_task =
-        GNUNET_SCHEDULER_add_delayed (GST_timeout, &lcf_forwarded_operation_timeout,
+        GNUNET_SCHEDULER_add_delayed (GST_timeout,
+                                      &lcf_forwarded_operation_timeout,
                                       lcf);
     lcf->state = FINISHED;
     break;
   case FINISHED:
-    lcfq = lcfq_head;
-    GNUNET_assert (lcfq->lcf == lcf);
-    GNUNET_SERVER_client_drop (lcf->client);
     if (NULL != lcf->op)
       GNUNET_TESTBED_operation_done (lcf->op);
+    GNUNET_CONTAINER_DLL_remove (lcf_head,
+                                 lcf_tail,
+                                 lcf);
     GNUNET_free (lcf);
-    GNUNET_CONTAINER_DLL_remove (lcfq_head, lcfq_tail, lcfq);
-    GNUNET_free (lcfq);
-    if (NULL != lcfq_head)
-      lcf_proc_task_id =
-          GNUNET_SCHEDULER_add_now (&lcf_proc_task, lcfq_head->lcf);
+    if (NULL != lcf_head)
+      lcf_proc_task_id = GNUNET_SCHEDULER_add_now (&lcf_proc_task,
+                                                   lcf_head);
   }
 }
 
@@ -770,12 +792,13 @@ slave_event_cb (void *cls, const struct GNUNET_TESTBED_EventInformation *event)
  *
  * @param cls the handle to the slave whose status is to be found here
  * @param cfg the configuration with which the controller has been started;
- *          NULL if status is not GNUNET_OK
- * @param status GNUNET_OK if the startup is successfull; GNUNET_SYSERR if not,
+ *          NULL if status is not #GNUNET_OK
+ * @param status #GNUNET_OK if the startup is successfull; #GNUNET_SYSERR if not,
  *          GNUNET_TESTBED_controller_stop() shouldn't be called in this case
  */
 static void
-slave_status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg,
+slave_status_cb (void *cls,
+                 const struct GNUNET_CONFIGURATION_Handle *cfg,
                  int status)
 {
   struct Slave *slave = cls;
@@ -789,7 +812,7 @@ slave_status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg,
        and as these tasks they depend on the operation queues which are created
        through GNUNET_TESTBED_controller_connect() and in kill_slave() we call
        the destructor function GNUNET_TESTBED_controller_disconnect() */
-    GST_free_lcfq ();
+    GST_free_lcf ();
     kill_slave (slave);
     destroy_slave (slave);
     slave = NULL;
@@ -819,8 +842,7 @@ slave_status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg,
   {
     if (NULL != lcc->client)
     {
-      GNUNET_SERVER_receive_done (lcc->client, GNUNET_OK);
-      GNUNET_SERVER_client_drop (lcc->client);
+      GNUNET_SERVICE_client_continue (lcc->client);
       lcc->client = NULL;
     }
     GNUNET_free (lcc);
@@ -1051,8 +1073,9 @@ cleanup_ncc (struct NeighbourConnectCtxt *ncc)
     GST_neighbour_get_connection_cancel (ncc->nh);
   if (NULL != ncc->timeout_task)
     GNUNET_SCHEDULER_cancel (ncc->timeout_task);
-  GNUNET_SERVER_client_drop (ncc->client);
-  GNUNET_CONTAINER_DLL_remove (ncc_head, ncc_tail, ncc);
+  GNUNET_CONTAINER_DLL_remove (ncc_head,
+                               ncc_tail,
+                               ncc);
   GNUNET_free (ncc);
 }
 
@@ -1061,7 +1084,7 @@ cleanup_ncc (struct NeighbourConnectCtxt *ncc)
  * Cleans up the neighbour list
  */
 void
-GST_neighbour_list_clean()
+GST_neighbour_list_clean ()
 {
   struct Neighbour *n;
   unsigned int id;
@@ -1091,8 +1114,7 @@ GST_get_neighbour (uint32_t id)
 {
   if (neighbour_list_size <= id)
     return NULL;
-  else
-    return neighbour_list[id];
+  return neighbour_list[id];
 }
 
 
@@ -1118,7 +1140,9 @@ timeout_neighbour_connect (void *cls)
  struct NeighbourConnectCtxt *ncc = cls;
 
  ncc->timeout_task = NULL;
- send_controller_link_response (ncc->client, ncc->op_id, NULL,
+ send_controller_link_response (ncc->client,
+                                ncc->op_id,
+                                NULL,
                                 "Could not connect to delegated controller");
  cleanup_ncc (ncc);
 }
@@ -1131,7 +1155,8 @@ timeout_neighbour_connect (void *cls)
  * @param c the handle the neighbour's controller
  */
 static void
-neighbour_connect_cb (void *cls, struct GNUNET_TESTBED_Controller *c)
+neighbour_connect_cb (void *cls,
+                      struct GNUNET_TESTBED_Controller *c)
 {
   struct NeighbourConnectCtxt *ncc = cls;
 
@@ -1139,7 +1164,10 @@ neighbour_connect_cb (void *cls, struct GNUNET_TESTBED_Controller *c)
   ncc->timeout_task = NULL;
   ncc->nh = NULL;
   GST_neighbour_release_connection (ncc->n);
-  send_controller_link_response (ncc->client, ncc->op_id, NULL, NULL);
+  send_controller_link_response (ncc->client,
+                                 ncc->op_id,
+                                 NULL,
+                                 NULL);
   cleanup_ncc (ncc);
 }
 
@@ -1162,18 +1190,17 @@ GST_create_neighbour (struct GNUNET_TESTBED_Host *host)
 
 
 /**
- * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_LCONTROLLERS message
+ * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_LCONTROLLERS message
  *
- * @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_link_controllers (void *cls, struct GNUNET_SERVER_Client *client,
-                             const struct GNUNET_MessageHeader *message)
+handle_link_controllers (void *cls,
+                         const struct GNUNET_TESTBED_ControllerLinkRequest *msg)
 {
-  const struct GNUNET_TESTBED_ControllerLinkRequest *msg;
-  struct LCFContextQueue *lcfq;
+  struct GNUNET_SERVICE_Client *client = cls;
+  struct LCFContext *lcf;
   struct Route *route;
   struct Route *new_route;
   uint64_t op_id;
@@ -1183,39 +1210,42 @@ GST_handle_link_controllers (void *cls, struct GNUNET_SERVER_Client *client,
   if (NULL == GST_context)
   {
     GNUNET_break (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+    GNUNET_SERVICE_client_drop (client);
     return;
   }
-  msg = (const struct GNUNET_TESTBED_ControllerLinkRequest *) message;
   delegated_host_id = ntohl (msg->delegated_host_id);
   if (delegated_host_id == GST_context->host_id)
   {
     GNUNET_break (0);
-    LOG (GNUNET_ERROR_TYPE_WARNING, "Trying to link ourselves\n");
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+    LOG (GNUNET_ERROR_TYPE_WARNING,
+         "Trying to link ourselves\n");
+    GNUNET_SERVICE_client_drop (client);
     return;
   }
   if ((delegated_host_id >= GST_host_list_size) ||
       (NULL == GST_host_list[delegated_host_id]))
   {
     LOG (GNUNET_ERROR_TYPE_WARNING,
-         "Delegated host %u not registered with us\n", delegated_host_id);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+         "Delegated host %u not registered with us\n",
+         delegated_host_id);
+    GNUNET_SERVICE_client_drop (client);
     return;
   }
   slave_host_id = ntohl (msg->slave_host_id);
   if ((slave_host_id >= GST_host_list_size) ||
       (NULL == GST_host_list[slave_host_id]))
   {
-    LOG (GNUNET_ERROR_TYPE_WARNING, "Slave host %u not registered with us\n",
+    LOG (GNUNET_ERROR_TYPE_WARNING,
+         "Slave host %u not registered with us\n",
          slave_host_id);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+    GNUNET_SERVICE_client_drop (client);
     return;
   }
   if (slave_host_id == delegated_host_id)
   {
-    LOG (GNUNET_ERROR_TYPE_WARNING, "Slave and delegated host are same\n");
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+    LOG (GNUNET_ERROR_TYPE_WARNING,
+         "Slave and delegated host are same\n");
+    GNUNET_SERVICE_client_drop (client);
     return;
   }
   op_id = GNUNET_ntohll (msg->operation_id);
@@ -1224,7 +1254,6 @@ GST_handle_link_controllers (void *cls, struct GNUNET_SERVER_Client *client,
     struct Slave *slave;
     struct LinkControllersContext *lcc;
 
-
     if (1 != msg->is_subordinate)
     {
       struct Neighbour *n;
@@ -1234,7 +1263,7 @@ GST_handle_link_controllers (void *cls, struct GNUNET_SERVER_Client *client,
         (NULL != neighbour_list[delegated_host_id]))
       {
         GNUNET_break (0);
-        GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+        GNUNET_SERVICE_client_drop (client);
         return;
       }
       LOG_DEBUG ("Received request to establish a link to host %u\n",
@@ -1244,37 +1273,42 @@ GST_handle_link_controllers (void *cls, struct GNUNET_SERVER_Client *client,
       ncc->n = n;
       ncc->op_id = op_id;
       ncc->client = client;
-      GNUNET_SERVER_client_keep (client);
-      ncc->nh = GST_neighbour_get_connection (n, neighbour_connect_cb, ncc);
-      ncc->timeout_task = GNUNET_SCHEDULER_add_delayed (GST_timeout,
-                                                        &timeout_neighbour_connect,
-                                                        ncc);
-      GNUNET_CONTAINER_DLL_insert_tail (ncc_head, ncc_tail, ncc);
-      GNUNET_SERVER_receive_done (client, GNUNET_OK);
+      ncc->nh = GST_neighbour_get_connection (n,
+                                              &neighbour_connect_cb,
+                                              ncc);
+      ncc->timeout_task
+        = GNUNET_SCHEDULER_add_delayed (GST_timeout,
+                                        &timeout_neighbour_connect,
+                                        ncc);
+      GNUNET_CONTAINER_DLL_insert_tail (ncc_head,
+                                        ncc_tail,
+                                        ncc);
+      GNUNET_SERVICE_client_continue (client);
       return;
     }
-    if ((delegated_host_id < GST_slave_list_size) &&
-        (NULL != GST_slave_list[delegated_host_id]))
+    if ( (delegated_host_id < GST_slave_list_size) &&
+         (NULL != GST_slave_list[delegated_host_id]) )
     {
       GNUNET_break (0);
-      GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+      GNUNET_SERVICE_client_drop (client);
       return;
     }
     LOG_DEBUG ("Received request to start and establish a link to host %u\n",
                delegated_host_id);
     slave = GNUNET_new (struct Slave);
     slave->host_id = delegated_host_id;
-    slave->reghost_map = GNUNET_CONTAINER_multihashmap_create (100, GNUNET_NO);
+    slave->reghost_map = GNUNET_CONTAINER_multihashmap_create (100,
+                                                               GNUNET_NO);
     slave_list_add (slave);
     lcc = GNUNET_new (struct LinkControllersContext);
     lcc->operation_id = op_id;
-    GNUNET_SERVER_client_keep (client);
     lcc->client = client;
     slave->lcc = lcc;
-    slave->controller_proc =
-        GNUNET_TESTBED_controller_start (GST_context->master_ip,
+    slave->controller_proc
+      = GNUNET_TESTBED_controller_start (GST_context->master_ip,
                                          GST_host_list[slave->host_id],
-                                         &slave_status_cb, slave);
+                                         &slave_status_cb,
+                                         slave);
     new_route = GNUNET_new (struct Route);
     new_route->dest = delegated_host_id;
     new_route->thru = GST_context->host_id;
@@ -1285,52 +1319,114 @@ GST_handle_link_controllers (void *cls, struct GNUNET_SERVER_Client *client,
   /* Route the request */
   if (slave_host_id >= route_list_size)
   {
-    LOG (GNUNET_ERROR_TYPE_WARNING, "No route towards slave host");
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+    LOG (GNUNET_ERROR_TYPE_WARNING,
+         "No route towards slave host");
+    GNUNET_SERVICE_client_drop (client);
     return;
   }
-  lcfq = GNUNET_new (struct LCFContextQueue);
-  lcfq->lcf = GNUNET_new (struct LCFContext);
-  lcfq->lcf->delegated_host_id = delegated_host_id;
-  lcfq->lcf->slave_host_id = slave_host_id;
+  lcf = GNUNET_new (struct LCFContext);
+  lcf->delegated_host_id = delegated_host_id;
+  lcf->slave_host_id = slave_host_id;
   route = GST_find_dest_route (slave_host_id);
   GNUNET_assert (NULL != route);        /* because we add routes carefully */
   GNUNET_assert (route->dest < GST_slave_list_size);
   GNUNET_assert (NULL != GST_slave_list[route->dest]);
-  lcfq->lcf->is_subordinate = msg->is_subordinate;
-  lcfq->lcf->state = INIT;
-  lcfq->lcf->operation_id = op_id;
-  lcfq->lcf->gateway = GST_slave_list[route->dest];
-  GNUNET_SERVER_client_keep (client);
-  lcfq->lcf->client = client;
-  if (NULL == lcfq_head)
+  lcf->is_subordinate = msg->is_subordinate;
+  lcf->state = INIT;
+  lcf->operation_id = op_id;
+  lcf->gateway = GST_slave_list[route->dest];
+  lcf->client = client;
+  if (NULL == lcf_head)
   {
     GNUNET_assert (NULL == lcf_proc_task_id);
-    GNUNET_CONTAINER_DLL_insert_tail (lcfq_head, lcfq_tail, lcfq);
-    lcf_proc_task_id = GNUNET_SCHEDULER_add_now (&lcf_proc_task, lcfq->lcf);
+    GNUNET_CONTAINER_DLL_insert_tail (lcf_head,
+                                      lcf_tail,
+                                      lcf);
+    lcf_proc_task_id = GNUNET_SCHEDULER_add_now (&lcf_proc_task,
+                                                 lcf);
   }
   else
-    GNUNET_CONTAINER_DLL_insert_tail (lcfq_head, lcfq_tail, lcfq);
+  {
+    GNUNET_CONTAINER_DLL_insert_tail (lcf_head,
+                                      lcf_tail,
+                                      lcf);
+  }
   /* FIXME: Adding a new route should happen after the controllers are linked
    * successfully */
   if (1 != msg->is_subordinate)
   {
-    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    GNUNET_SERVICE_client_continue (client);
     return;
   }
-  if ((delegated_host_id < route_list_size) &&
-      (NULL != route_list[delegated_host_id]))
+  if ( (delegated_host_id < route_list_size) &&
+       (NULL != route_list[delegated_host_id]) )
   {
     GNUNET_break_op (0);        /* Are you trying to link delegated host twice
                                  * with is subordinate flag set to GNUNET_YES? */
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+    GNUNET_SERVICE_client_drop (client);
     return;
   }
   new_route = GNUNET_new (struct Route);
   new_route->dest = delegated_host_id;
   new_route->thru = route->dest;
   route_list_add (new_route);
-  GNUNET_SERVER_receive_done (client, GNUNET_OK);
+  GNUNET_SERVICE_client_continue (client);
+}
+
+
+/**
+ * Clean up @a client handle if we stored any via #handle_link_controllers(),
+ * the given client disconnected.
+ *
+ * @param client the client that is history
+ */
+void
+GST_link_notify_disconnect (struct GNUNET_SERVICE_Client *client)
+{
+  struct NeighbourConnectCtxt *ncc;
+  struct NeighbourConnectCtxt *nccn;
+  struct LCFContext *lcf;
+  struct LCFContext *lcfn;
+
+  for (ncc = ncc_head; NULL != ncc; ncc = nccn)
+  {
+    nccn = ncc->next;
+    if (ncc->client == client)
+      cleanup_ncc (ncc);
+  }
+  for (unsigned int i=0;i<GST_slave_list_size;i++)
+  {
+    struct Slave *slave = GST_slave_list[i];
+    struct LinkControllersContext *lcc;
+
+    if (NULL == slave)
+      continue;
+    GNUNET_CONTAINER_multihashmap_iterate (slave->reghost_map,
+                                           &drop_client_entries,
+                                           client);
+    lcc = slave->lcc;
+    if (NULL == lcc)
+      continue;
+    if (lcc->client == client)
+    {
+      slave->lcc = NULL;
+      GNUNET_free (lcc);
+    }
+  }
+  for (lcf = lcf_head; NULL != lcf; lcf = lcfn)
+  {
+    lcfn = lcf->next;
+    if ( (NULL != lcf) &&
+         (client == lcf->client) )
+    {
+      if (NULL != lcf->op)
+        GNUNET_TESTBED_operation_done (lcf->op);
+      GNUNET_CONTAINER_DLL_remove (lcf_head,
+                                   lcf_tail,
+                                   lcf);
+      GNUNET_free (lcf);
+    }
+  }
 }
 
 
@@ -1338,12 +1434,11 @@ GST_handle_link_controllers (void *cls, struct GNUNET_SERVER_Client *client,
  * Cleans up the queue used for forwarding link controllers requests
  */
 void
-GST_free_lcfq ()
+GST_free_lcf ()
 {
-  struct LCFContextQueue *lcfq;
   struct LCFContext *lcf;
 
-  if (NULL != lcfq_head)
+  if (NULL != lcf_head)
   {
     if (NULL != lcf_proc_task_id)
     {
@@ -1352,16 +1447,15 @@ GST_free_lcfq ()
     }
   }
   GNUNET_assert (NULL == lcf_proc_task_id);
-  for (lcfq = lcfq_head; NULL != lcfq; lcfq = lcfq_head)
+  for (lcf = lcf_head; NULL != lcf; lcf = lcf_head)
   {
-    lcf = lcfq->lcf;
-    GNUNET_SERVER_client_drop (lcf->client);
     if (NULL != lcf->op)
       GNUNET_TESTBED_operation_done (lcf->op);
     if (NULL != lcf->timeout_task)
       GNUNET_SCHEDULER_cancel (lcf->timeout_task);
+    GNUNET_CONTAINER_DLL_remove (lcf_head,
+                                 lcf_tail,
+                                 lcf);
     GNUNET_free (lcf);
-    GNUNET_CONTAINER_DLL_remove (lcfq_head, lcfq_tail, lcfq);
-    GNUNET_free (lcfq);
   }
 }
index b39851ed7b7a998344ea8a9ec36f12364b72139a..09764b99aca6ca4cb6e033854ed7155084677936 100644 (file)
@@ -94,7 +94,7 @@ extern unsigned int GST_slave_list_size;
  * Cleans up the neighbour list
  */
 void
-GST_neighbour_list_clean();
+GST_neighbour_list_clean (void);
 
 
 /**
@@ -112,7 +112,7 @@ GST_get_neighbour (uint32_t id);
  * Function to cleanup the neighbour connect contexts
  */
 void
-GST_free_nccq ();
+GST_free_nccq (void);
 
 
 /**
@@ -128,10 +128,9 @@ struct NeighbourConnectNotification;
  * @param cls the closure given to GST_neighbour_get_connection()
  * @param controller the controller handle to the neighbour
  */
-typedef void (*GST_NeigbourConnectNotifyCallback) (void *cls,
-                                                   struct
-                                                   GNUNET_TESTBED_Controller
-                                                   *controller);
+typedef void
+(*GST_NeigbourConnectNotifyCallback) (void *cls,
+                                      struct GNUNET_TESTBED_Controller *controller);
 
 
 /**
@@ -181,19 +180,28 @@ GST_create_neighbour (struct GNUNET_TESTBED_Host *host);
 
 
 /**
- * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_LCONTROLLERS message
+ * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_LCONTROLLERS message
  *
- * @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_link_controllers (void *cls, struct GNUNET_SERVER_Client *client,
-                             const struct GNUNET_MessageHeader *message);
+handle_link_controllers (void *cls,
+                         const struct GNUNET_TESTBED_ControllerLinkRequest *msg);
+
+
+/**
+ * Clean up @a client handle if we stored any via #handle_link_controllers(),
+ * the given client disconnected.
+ *
+ * @param client the client that is history
+ */
+void
+GST_link_notify_disconnect (struct GNUNET_SERVICE_Client *client);
 
 
 /**
  * Cleans up the slave list
  */
 void
-GST_slave_list_clear ();
+GST_slave_list_clear (void);
index c681c38100050b56667dac531f216be0261c8ff2..b775f31bd9174befcc41620ca4a182138d165161 100644 (file)
@@ -168,7 +168,7 @@ struct OverlayConnectContext
    * The client which has requested for overlay connection. This is used to send
    * either a success of failure message
    */
-  struct GNUNET_SERVER_Client *client;
+  struct GNUNET_SERVICE_Client *client;
 
   /**
    * the first peer which is to expect an overlay connection from the second peer.
@@ -358,7 +358,11 @@ static struct RemoteOverlayConnectCtx *roccq_tail;
 void
 GST_cleanup_focc (struct ForwardedOverlayConnectContext *focc)
 {
-  GNUNET_SERVER_client_drop (focc->client);
+  struct RegisteredHostContext *rhc = focc->rhc;
+
+  GNUNET_CONTAINER_DLL_remove (rhc->focc_dll_head,
+                               rhc->focc_dll_tail,
+                               focc);
   GNUNET_free_non_null (focc->orig_msg);
   GNUNET_free (focc);
 }
@@ -376,10 +380,11 @@ forwarded_overlay_connect_timeout (void *cls)
   struct RegisteredHostContext *rhc;
   struct ForwardedOverlayConnectContext *focc;
 
+  fopc->timeout_task = NULL;
   rhc = fopc->cls;
   focc = rhc->focc_dll_head;
-  GNUNET_CONTAINER_DLL_remove (rhc->focc_dll_head, rhc->focc_dll_tail, focc);
-  LOG_DEBUG ("Overlay linking between peers %u and %u failed\n", focc->peer1,
+  LOG_DEBUG ("Overlay linking between peers %u and %u failed\n",
+             focc->peer1,
              focc->peer2);
   GST_cleanup_focc (focc);
   GST_forwarded_operation_timeout (fopc);
@@ -407,7 +412,6 @@ forwarded_overlay_connect_listener (void *cls,
   rhc = fopc->cls;
   GST_forwarded_operation_reply_relay (cls, msg);
   focc = rhc->focc_dll_head;
-  GNUNET_CONTAINER_DLL_remove (rhc->focc_dll_head, rhc->focc_dll_tail, focc);
   GST_cleanup_focc (focc);
   if (NULL != rhc->focc_dll_head)
     GST_process_next_focc (rhc);
@@ -435,22 +439,24 @@ GST_process_next_focc (struct RegisteredHostContext *rhc)
   GNUNET_assert (GNUNET_YES == peer->is_remote);
   GNUNET_assert (NULL != (slave = peer->details.remote.slave));
   fopc = GNUNET_new (struct ForwardedOperationContext);
-  GNUNET_SERVER_client_keep (focc->client);
   fopc->client = focc->client;
   fopc->operation_id = focc->operation_id;
   fopc->cls = rhc;
   fopc->type = OP_OVERLAY_CONNECT;
   fopc->opc =
       GNUNET_TESTBED_forward_operation_msg_ (slave->controller,
-                                             focc->operation_id, focc->orig_msg,
+                                             focc->operation_id,
+                                             focc->orig_msg,
                                              &forwarded_overlay_connect_listener,
                                              fopc);
   GNUNET_free (focc->orig_msg);
   focc->orig_msg = NULL;
-  fopc->timeout_task =
-      GNUNET_SCHEDULER_add_delayed (GST_timeout, &forwarded_overlay_connect_timeout,
+  fopc->timeout_task = GNUNET_SCHEDULER_add_delayed (GST_timeout,
+                                                     &forwarded_overlay_connect_timeout,
+                                                     fopc);
+  GNUNET_CONTAINER_DLL_insert_tail (fopcq_head,
+                                    fopcq_tail,
                                     fopc);
-  GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc);
 }
 
 
@@ -533,7 +539,6 @@ cleanup_occ (struct OverlayConnectContext *occ)
              occ->op_id);
   GNUNET_free_non_null (occ->emsg);
   GNUNET_free_non_null (occ->hello);
-  GNUNET_SERVER_client_drop (occ->client);
   if (NULL != occ->send_hello_task)
     GNUNET_SCHEDULER_cancel (occ->send_hello_task);
   if (NULL != occ->cleanup_task)
@@ -609,25 +614,59 @@ timeout_overlay_connect (void *cls)
 }
 
 
+/**
+ * Notify OC subsystem that @a client disconnected.
+ *
+ * @param client the client that disconnected
+ */
+void
+GST_notify_client_disconnect_oc (struct GNUNET_SERVICE_Client *client)
+{
+  struct ForwardedOperationContext *fopc;
+  struct ForwardedOperationContext *fopcn;
+  struct OverlayConnectContext *occ;
+  struct OverlayConnectContext *occn;
+
+  for (fopc = fopcq_head; NULL != fopc; fopc = fopcn)
+  {
+    fopcn = fopc->next;
+    if (fopc->client == client)
+    {
+      GNUNET_SCHEDULER_cancel (fopc->timeout_task);
+      GST_forwarded_operation_timeout (fopc);
+    }
+  }
+  for (occ = occq_head; NULL != occ; occ = occn)
+  {
+    occn = occ->next;
+    if (occ->client == client)
+      cleanup_occ (occ);
+  }
+  // FIXME: implement clean up for client_keep replacements!
+}
+
+
+
+
 /**
  * FIXME.
  */
 static void
 send_overlay_connect_success_msg (struct OverlayConnectContext *occ)
 {
+  struct GNUNET_MQ_Envelope *env;
   struct GNUNET_TESTBED_ConnectionEventMessage *msg;
 
   LOG_DEBUG ("0x%llx: Peers connected - Sending overlay connect success\n",
              occ->op_id);
-  msg = GNUNET_new (struct GNUNET_TESTBED_ConnectionEventMessage);
-  msg->header.size =
-      htons (sizeof (struct GNUNET_TESTBED_ConnectionEventMessage));
-  msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_PEER_CONNECT_EVENT);
+  env = GNUNET_MQ_msg (msg,
+                       GNUNET_MESSAGE_TYPE_TESTBED_PEER_CONNECT_EVENT);
   msg->event_type = htonl (GNUNET_TESTBED_ET_CONNECT);
   msg->peer1 = htonl (occ->peer->id);
   msg->peer2 = htonl (occ->other_peer_id);
   msg->operation_id = GNUNET_htonll (occ->op_id);
-  GST_queue_message (occ->client, &msg->header);
+  GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (occ->client),
+                  env);
 }
 
 
@@ -1314,7 +1353,8 @@ register_host (struct Slave *slave,
   rhc->state = RHC_INIT;
   hash = hash_hosts (rhc->reg_host, rhc->host);
   if ((GNUNET_NO ==
-       GNUNET_CONTAINER_multihashmap_contains (slave->reghost_map, &hash)) ||
+       GNUNET_CONTAINER_multihashmap_contains (slave->reghost_map,
+                                               &hash)) ||
       (GNUNET_SYSERR !=
        GNUNET_CONTAINER_multihashmap_get_multiple (slave->reghost_map,
                                                    &hash,
@@ -1323,10 +1363,14 @@ register_host (struct Slave *slave,
   {
     /* create and add a new registerd host context */
     /* add the focc to its queue */
-    GNUNET_CONTAINER_multihashmap_put (slave->reghost_map, &hash, rhc,
+    GNUNET_CONTAINER_multihashmap_put (slave->reghost_map,
+                                       &hash,
+                                       rhc,
                                        GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
-    GST_queue_host_registration (slave, host_registration_comp,
-                                 rhc, rhc->reg_host);
+    GST_queue_host_registration (slave,
+                                 host_registration_comp,
+                                 rhc,
+                                 rhc->reg_host);
   }
   else
   {
@@ -1352,7 +1396,7 @@ register_host (struct Slave *slave,
  */
 static void
 forward_overlay_connect (const struct GNUNET_TESTBED_OverlayConnectMessage *msg,
-                         struct GNUNET_SERVER_Client *client)
+                         struct GNUNET_SERVICE_Client *client)
 {
   struct ForwardedOperationContext *fopc;
   struct Route *route_to_peer2_host;
@@ -1388,14 +1432,15 @@ forward_overlay_connect (const struct GNUNET_TESTBED_OverlayConnectMessage *msg,
   {
     LOG_DEBUG ("Queueing forwarding FOCC for connecting peers %u and %u\n", p1, p2);
     focc = GNUNET_new (struct ForwardedOverlayConnectContext);
+    focc->rhc = rhc;
     focc->peer1 = p1;
     focc->peer2 = p2;
     focc->peer2_host_id = peer2_host_id;
     focc->orig_msg = GNUNET_copy_message (&msg->header);
     focc->operation_id = op_id;
     focc->client = client;
-    GNUNET_SERVER_client_keep (client);
-    GNUNET_CONTAINER_DLL_insert_tail (rhc->focc_dll_head, rhc->focc_dll_tail,
+    GNUNET_CONTAINER_DLL_insert_tail (rhc->focc_dll_head,
+                                      rhc->focc_dll_tail,
                                       focc);
     return;
   }
@@ -1403,7 +1448,6 @@ forward_overlay_connect (const struct GNUNET_TESTBED_OverlayConnectMessage *msg,
  forward:
   LOG_DEBUG ("Forwarding without FOCC for connecting peers %u and %u\n", p1, p2);
   fopc = GNUNET_new (struct ForwardedOperationContext);
-  GNUNET_SERVER_client_keep (client);
   fopc->client = client;
   fopc->operation_id = op_id;
   fopc->type = OP_OVERLAY_CONNECT;
@@ -1450,7 +1494,8 @@ p2_controller_connect_cb (void *cls,
   cmsg.operation_id = GNUNET_htonll (occ->op_id);
   rp2c->opc =
       GNUNET_TESTBED_forward_operation_msg_ (rp2c->p2c,
-                                             occ->op_id, &cmsg.header,
+                                             occ->op_id,
+                                             &cmsg.header,
                                              &overlay_connect_get_config,
                                              occ);
   GNUNET_free_non_null (occ->emsg);
@@ -1463,18 +1508,16 @@ p2_controller_connect_cb (void *cls,
 
 
 /**
- * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_OLCONNECT messages
+ * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_OVERLAY_CONNECT 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_overlay_connect (void *cls,
-                            struct GNUNET_SERVER_Client *client,
-                            const struct GNUNET_MessageHeader *message)
+handle_overlay_connect (void *cls,
+                        const struct GNUNET_TESTBED_OverlayConnectMessage *msg)
 {
-  const struct GNUNET_TESTBED_OverlayConnectMessage *msg;
+  struct GNUNET_SERVICE_Client *client = cls;
   struct Peer *peer;
   struct Peer *peer2;
   struct OverlayConnectContext *occ;
@@ -1484,20 +1527,12 @@ GST_handle_overlay_connect (void *cls,
   uint32_t p2;
   uint32_t peer2_host_id;
 
-  if (sizeof (struct GNUNET_TESTBED_OverlayConnectMessage) !=
-      ntohs (message->size))
-  {
-    GNUNET_break (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
-    return;
-  }
-  msg = (const struct GNUNET_TESTBED_OverlayConnectMessage *) message;
   p1 = ntohl (msg->peer1);
   p2 = ntohl (msg->peer2);
-  if (!VALID_PEER_ID (p1))
+  if (! VALID_PEER_ID (p1))
   {
     GNUNET_break (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+    GNUNET_SERVICE_client_drop (client);
     return;
   }
   peer = GST_peer_list[p1];
@@ -1513,30 +1548,27 @@ GST_handle_overlay_connect (void *cls,
     if (! VALID_HOST_ID (peer2_host_id))
     {
       GNUNET_break (0);
-      GNUNET_SERVER_receive_done (client,
-                                  GNUNET_SYSERR);
+      GNUNET_SERVICE_client_drop (client);
       return;
     }
     forward_overlay_connect (msg, client);
-    GNUNET_SERVER_receive_done (client,
-                                GNUNET_OK);
+    GNUNET_SERVICE_client_continue (client);
     return;
   }
   p2n = NULL;
   occ = GNUNET_new (struct OverlayConnectContext);
   occ->type = OCC_TYPE_LOCAL;
-  if (!VALID_PEER_ID (p2))       /* May be peer2 is on a another controller */
+  if (! VALID_PEER_ID (p2))       /* May be peer2 is on a another controller */
   {
     if (NULL == (p2n = GST_get_neighbour (peer2_host_id)))
     {
-      if (!VALID_HOST_ID (peer2_host_id))
+      if (! VALID_HOST_ID (peer2_host_id))
       {
         GNUNET_break (0);
         LOG (GNUNET_ERROR_TYPE_WARNING,
              "0x%llx: Peer %u's host not in our neighbours list\n",
              operation_id, p2);
-        GNUNET_SERVER_receive_done (client,
-                                    GNUNET_SYSERR);
+        GNUNET_SERVICE_client_drop (client);
         GNUNET_free (occ);
         return;
       }
@@ -1553,7 +1585,6 @@ GST_handle_overlay_connect (void *cls,
   GNUNET_CONTAINER_DLL_insert_tail (occq_head,
                                     occq_tail,
                                     occ);
-  GNUNET_SERVER_client_keep (client);
   occ->client = client;
   occ->other_peer_id = p2;
   GST_peer_list[p1]->reference_cnt++;
@@ -1573,11 +1604,14 @@ GST_handle_overlay_connect (void *cls,
                      occ->op_id,
                      occ->other_peer_id,
                      peer2_host_id);
-    occ->p2ctx.remote.ncn =
-        GST_neighbour_get_connection (p2n, &p2_controller_connect_cb, occ);
+    occ->p2ctx.remote.ncn
+      = GST_neighbour_get_connection (p2n,
+                                      &p2_controller_connect_cb,
+                                      occ);
     break;
   case OCC_TYPE_REMOTE_SLAVE:
-    p2_controller_connect_cb (occ, occ->p2ctx.remote.p2c);
+    p2_controller_connect_cb (occ,
+                              occ->p2ctx.remote.p2c);
     break;
   case OCC_TYPE_LOCAL:
     peer2 = GST_peer_list[occ->other_peer_id];
@@ -1598,7 +1632,7 @@ GST_handle_overlay_connect (void *cls,
                                         &overlay_connect_notify, occ);
     break;
   }
-  GNUNET_SERVER_receive_done (client, GNUNET_OK);
+  GNUNET_SERVICE_client_continue (client);
 }
 
 
@@ -1793,64 +1827,72 @@ rocc_cache_get_handle_transport_cb (void *cls,
 
 
 /**
- * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_REQUEST_CONNECT messages
+ * Check #GNUNET_MESSAGE_TYPE_TESTBED_REMOTE_OVERLAY_CONNECT 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
  */
-void
-GST_handle_remote_overlay_connect (void *cls,
-                                   struct GNUNET_SERVER_Client *client,
-                                   const struct GNUNET_MessageHeader *message)
+int
+check_remote_overlay_connect (void *cls,
+                               const struct GNUNET_TESTBED_RemoteOverlayConnectMessage *msg)
 {
-  const struct GNUNET_TESTBED_RemoteOverlayConnectMessage *msg;
-  struct RemoteOverlayConnectCtx *rocc;
-  struct Peer *peer;
-  struct GNUNET_PeerIdentity pid;
-  static char pid_str[16];
   uint32_t peer_id;
   uint16_t msize;
   uint16_t hsize;
 
-  msize = ntohs (message->size);
-  if (sizeof (struct GNUNET_TESTBED_RemoteOverlayConnectMessage) >= msize)
-  {
-    GNUNET_break (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
-    return;
-  }
-  msg = (const struct GNUNET_TESTBED_RemoteOverlayConnectMessage *) message;
+  msize = ntohs (msg->header.size);
   if (GNUNET_MESSAGE_TYPE_HELLO != ntohs (msg->hello->type))
   {
     GNUNET_break (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
-    return;
+    return GNUNET_SYSERR;
   }
   hsize = ntohs (msg->hello->size);
-  if ((sizeof (struct GNUNET_TESTBED_RemoteOverlayConnectMessage) + hsize) !=
-      msize)
+  if ((sizeof (struct GNUNET_TESTBED_RemoteOverlayConnectMessage) + hsize) != msize)
   {
     GNUNET_break (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
-    return;
+    return GNUNET_SYSERR;
   }
   peer_id = ntohl (msg->peer);
   if ((peer_id >= GST_peer_list_size) ||
-      (NULL == (peer = GST_peer_list[peer_id])))
+      (NULL == GST_peer_list[peer_id]))
   {
     GNUNET_break_op (0);
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
-    return;
+    return GNUNET_SYSERR;
   }
+  return GNUNET_OK;
+}
+
+
+/**
+ * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_REMOTE_OVERLAY_CONNECT messages
+ *
+ * @param cls identification of the client
+ * @param msg the actual message
+ */
+void
+handle_remote_overlay_connect (void *cls,
+                               const struct GNUNET_TESTBED_RemoteOverlayConnectMessage *msg)
+{
+  struct GNUNET_SERVICE_Client *client = cls;
+  struct RemoteOverlayConnectCtx *rocc;
+  struct Peer *peer;
+  struct GNUNET_PeerIdentity pid;
+  static char pid_str[16];
+  uint32_t peer_id;
+  uint16_t hsize;
+
+  hsize = ntohs (msg->hello->size);
+  peer_id = ntohl (msg->peer);
+  peer = GST_peer_list[peer_id];
   if (GNUNET_YES == peer->is_remote)
   {
     struct GNUNET_MessageHeader *msg2;
 
-    msg2 = GNUNET_copy_message (message);
+    msg2 = GNUNET_copy_message (&msg->header);
     GNUNET_TESTBED_queue_message_ (peer->details.remote.slave->controller,
                                    msg2);
-    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    GNUNET_SERVICE_client_continue (client);
     return;
   }
   rocc = GNUNET_new (struct RemoteOverlayConnectCtx);
@@ -1872,7 +1914,9 @@ GST_handle_remote_overlay_connect (void *cls,
   rocc->peer = peer;
   rocc->peer->reference_cnt++;
   rocc->hello = GNUNET_malloc (hsize);
-  GNUNET_memcpy (rocc->hello, msg->hello, hsize);
+  GNUNET_memcpy (rocc->hello,
+                 msg->hello,
+                 hsize);
   rocc->tcc.cgh_p2_th =
       GST_connection_pool_get_handle (peer_id,
                                       rocc->peer->details.local.cfg,
@@ -1886,8 +1930,7 @@ GST_handle_remote_overlay_connect (void *cls,
       GNUNET_SCHEDULER_add_delayed (GST_timeout,
                                     &timeout_rocc_task,
                                     rocc);
-  GNUNET_SERVER_receive_done (client,
-                              GNUNET_OK);
+  GNUNET_SERVICE_client_continue (client);
 }
 
 
index b55f5a8c8d4ea45da188b836a324dcb085bbac1f..a977b2b9b5f222c151e2aab20e325b8631bbbfab 100644 (file)
@@ -69,7 +69,7 @@ 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.
@@ -112,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
@@ -246,7 +246,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);
 }
 
 
@@ -277,6 +278,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
@@ -299,22 +409,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);
+}
+
+
+/**
+ * Check #GNUNET_MESSAGE_TYPE_TESTBED_CREATEPEER messages
+ *
+ * @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
+ * Handler for #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
  */
 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;
@@ -323,55 +449,54 @@ 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",
+    GNUNET_CONFIGURATION_set_value_number (cfg,
+                                           "PATHS",
+                                           "PEERID",
                                            (unsigned long long) peer_id);
     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,
@@ -379,24 +504,24 @@ GST_handle_peer_create (void *cls, struct GNUNET_SERVER_Client *client,
                                        &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_new (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;
   }
 
@@ -405,7 +530,7 @@ 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_new (struct Peer);
@@ -414,7 +539,6 @@ GST_handle_peer_create (void *cls, struct GNUNET_SERVER_Client *client,
   peer->details.remote.slave = GST_slave_list[route->dest];
   peer->details.remote.remote_host_id = host_id;
   fo_ctxt = GNUNET_new (struct ForwardedOperationContext);
-  GNUNET_SERVER_client_keep (client);
   fo_ctxt->client = client;
   fo_ctxt->operation_id = GNUNET_ntohll (msg->operation_id);
   fo_ctxt->cls = peer;
@@ -424,34 +548,34 @@ GST_handle_peer_create (void *cls, struct GNUNET_SERVER_Client *client,
                                              [route->dest]->controller,
                                              fo_ctxt->operation_id,
                                              &msg->header,
-                                             peer_create_success_cb, fo_ctxt);
+                                             &peer_create_success_cb,
+                                             fo_ctxt);
   fo_ctxt->timeout_task =
       GNUNET_SCHEDULER_add_delayed (GST_timeout,
                                     &peer_create_forward_timeout,
                                     fo_ctxt);
-  GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fo_ctxt);
-  GNUNET_SERVER_receive_done (client, GNUNET_OK);
+  GNUNET_CONTAINER_DLL_insert_tail (fopcq_head,
+                                    fopcq_tail,
+                                    fo_ctxt);
+  GNUNET_SERVICE_client_continue (client);
 }
 
 
 /**
  * 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: %llu\n",
              (unsigned int) peer_id,
@@ -460,9 +584,10 @@ GST_handle_peer_destroy (void *cls,
   {
     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];
@@ -470,7 +595,6 @@ GST_handle_peer_destroy (void *cls,
   {
     /* Forward the destory message to sub controller */
     fopc = GNUNET_new (struct ForwardedOperationContext);
-    GNUNET_SERVER_client_keep (client);
     fopc->client = client;
     fopc->cls = peer;
     fopc->type = OP_PEER_DESTROY;
@@ -478,14 +602,18 @@ GST_handle_peer_destroy (void *cls,
     fopc->opc =
         GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote.
                                                slave->controller,
-                                               fopc->operation_id, &msg->header,
-                                               &peer_destroy_success_cb, fopc);
+                                               fopc->operation_id,
+                                               &msg->header,
+                                               &peer_destroy_success_cb,
+                                               fopc);
     fopc->timeout_task =
         GNUNET_SCHEDULER_add_delayed (GST_timeout,
                                       &GST_forwarded_operation_timeout,
                                       fopc);
-    GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc);
-    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    GNUNET_CONTAINER_DLL_insert_tail (fopcq_head,
+                                      fopcq_tail,
+                                      fopc);
+    GNUNET_SERVICE_client_continue (client);
     return;
   }
   peer->destroy_flag = GNUNET_YES;
@@ -494,8 +622,9 @@ GST_handle_peer_destroy (void *cls,
   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);
 }
 
 
@@ -517,54 +646,36 @@ 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_new (struct ForwardedOperationContext);
-    GNUNET_SERVER_client_keep (client);
     fopc->client = client;
     fopc->operation_id = GNUNET_ntohll (msg->operation_id);
     fopc->type = OP_PEER_START;
@@ -578,58 +689,58 @@ GST_handle_peer_start (void *cls, struct GNUNET_SERVER_Client *client,
         GNUNET_SCHEDULER_add_delayed (GST_timeout,
                                       &GST_forwarded_operation_timeout,
                                       fopc);
-    GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc);
-    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    GNUNET_CONTAINER_DLL_insert_tail (fopcq_head,
+                                      fopcq_tail,
+                                      fopc);
+    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_new (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",
        (unsigned int) peer_id);
-  if (!VALID_PEER_ID (peer_id))
+  if (! VALID_PEER_ID (peer_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];
@@ -639,7 +750,6 @@ GST_handle_peer_stop (void *cls,
          "Forwarding PEER_STOP for peer %u\n",
          (unsigned int) peer_id);
     fopc = GNUNET_new (struct ForwardedOperationContext);
-    GNUNET_SERVER_client_keep (client);
     fopc->client = client;
     fopc->operation_id = GNUNET_ntohll (msg->operation_id);
     fopc->type = OP_PEER_STOP;
@@ -657,7 +767,7 @@ GST_handle_peer_stop (void *cls,
     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))
@@ -668,38 +778,37 @@ GST_handle_peer_stop (void *cls,
     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",
        (unsigned int) peer_id);
-  reply = GNUNET_new (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_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;
@@ -708,9 +817,7 @@ 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",
              (unsigned int) peer_id);
@@ -719,7 +826,7 @@ GST_handle_peer_get_config (void *cls, struct GNUNET_SERVER_Client *client,
     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];
@@ -728,7 +835,6 @@ GST_handle_peer_get_config (void *cls, struct GNUNET_SERVER_Client *client,
     LOG_DEBUG ("Forwarding PEER_GET_CONFIG for peer: %u\n",
                (unsigned int) peer_id);
     fopc = GNUNET_new (struct ForwardedOperationContext);
-    GNUNET_SERVER_client_keep (client);
     fopc->client = client;
     fopc->operation_id = GNUNET_ntohll (msg->operation_id);
     fopc->type = OP_PEER_INFO;
@@ -746,7 +852,7 @@ GST_handle_peer_get_config (void *cls, struct GNUNET_SERVER_Client *client,
     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",
@@ -758,47 +864,21 @@ GST_handle_peer_get_config (void *cls, struct GNUNET_SERVER_Client *client,
                                              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_INFORMATION);
+  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);
-}
-
-
-/**
- * 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_SERVER_client_drop (prc->client);
-  GNUNET_CONTAINER_DLL_remove (prc_head, prc_tail, prc);
-  GNUNET_free (prc);
+  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);
 }
 
 
@@ -886,21 +966,34 @@ prc_stop_cb (void *cls,
 }
 
 
+/**
+ * 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;
@@ -908,27 +1001,16 @@ GST_handle_peer_reconfigure (void *cls,
   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);
+    GNUNET_SERVICE_client_continue (client);
     return;
   }
   peer = GST_peer_list[peer_id];
@@ -936,7 +1018,6 @@ GST_handle_peer_reconfigure (void *cls,
   {
     LOG_DEBUG ("Forwarding PEER_RECONFIGURE for peer: %u\n", peer_id);
     fopc = GNUNET_new (struct ForwardedOperationContext);
-    GNUNET_SERVER_client_keep (client);
     fopc->client = client;
     fopc->operation_id = op_id;
     fopc->type = OP_PEER_RECONFIGURE;
@@ -954,7 +1035,7 @@ GST_handle_peer_reconfigure (void *cls,
     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",
@@ -965,8 +1046,7 @@ GST_handle_peer_reconfigure (void *cls,
     GST_send_operation_fail_msg (client,
                                  op_id,
                                  "Peer in use");
-    GNUNET_SERVER_receive_done (client,
-                                GNUNET_OK);
+    GNUNET_SERVICE_client_continue (client);
     return;
   }
   if (GNUNET_YES == peer->destroy_flag)
@@ -975,19 +1055,17 @@ GST_handle_peer_reconfigure (void *cls,
     GST_send_operation_fail_msg (client,
                                  op_id,
                                  "Peer is being destroyed");
-    GNUNET_SERVER_receive_done (client,
-                                GNUNET_OK);
+    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_SERVICE_client_continue (client);
     return;
   }
   if (GNUNET_NO == peer->details.local.is_running)
@@ -1000,8 +1078,7 @@ GST_handle_peer_reconfigure (void *cls,
                                    emsg);
     GST_send_operation_success_msg (client,
                                     op_id);
-    GNUNET_SERVER_receive_done (client,
-                                GNUNET_OK);
+    GNUNET_SERVICE_client_continue (client);
     GNUNET_free_non_null (emsg);
     return;
   }
@@ -1020,8 +1097,7 @@ GST_handle_peer_reconfigure (void *cls,
     GST_send_operation_fail_msg (client,
                                  op_id,
                                  emsg);
-    GNUNET_SERVER_receive_done (client,
-                                GNUNET_OK);
+    GNUNET_SERVICE_client_continue (client);
     GNUNET_free (prc);
     GNUNET_free (emsg);
     return;
@@ -1030,36 +1106,10 @@ GST_handle_peer_reconfigure (void *cls,
   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_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 (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);
+  GNUNET_SERVICE_client_continue (client);
 }
 
 
@@ -1211,51 +1261,57 @@ service_manage_result_cb (void *cls,
 
 
 /**
- * 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;
+  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",
@@ -1277,7 +1333,6 @@ GST_handle_manage_peer_service (void *cls,
   {
     /* Forward the destory message to sub controller */
     fopc = GNUNET_new (struct ForwardedOperationContext);
-    GNUNET_SERVER_client_keep (client);
     fopc->client = client;
     fopc->cls = peer;
     fopc->type = OP_MANAGE_SERVICE;
@@ -1296,7 +1351,7 @@ GST_handle_manage_peer_service (void *cls,
     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)
@@ -1326,7 +1381,6 @@ GST_handle_manage_peer_service (void *cls,
   peer->reference_cnt++;
   mctx->op_id = op_id;
   mctx->ah = ah;
-  GNUNET_SERVER_client_keep (client);
   mctx->client = client;
   mctx->start = msg->start;
   mctx->service = GNUNET_strdup (service);
@@ -1343,14 +1397,14 @@ GST_handle_manage_peer_service (void *cls,
     GNUNET_ARM_request_service_stop (mctx->ah, service,
                                      &service_manage_result_cb,
                                      mctx);
-  GNUNET_SERVER_receive_done (client, GNUNET_OK);
+  GNUNET_SERVICE_client_continue (client);
   return;
 
  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);
 }
 
 
@@ -1432,7 +1486,6 @@ shutdown_peers_reply_cb (void *cls,
     GNUNET_free (hc);
     hc = NULL;
   }
-  GNUNET_SERVER_client_drop (fo_ctxt->client);
   GNUNET_CONTAINER_DLL_remove (fopcq_head,
                                fopcq_tail,
                                fo_ctxt);
@@ -1443,23 +1496,20 @@ shutdown_peers_reply_cb (void *cls,
 /**
  * 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 */
   GST_free_mctxq ();
@@ -1481,7 +1531,6 @@ GST_handle_shutdown_peers (void *cls,
     LOG_DEBUG ("Forwarding SHUTDOWN_PEERS\n");
     hc->nslaves++;
     fo_ctxt = GNUNET_new (struct ForwardedOperationContext);
-    GNUNET_SERVER_client_keep (client);
     fo_ctxt->client = client;
     fo_ctxt->operation_id = op_id;
     fo_ctxt->cls = hc;
@@ -1504,6 +1553,5 @@ GST_handle_shutdown_peers (void *cls,
                                     op_id);
     GNUNET_free (hc);
   }
-  GNUNET_SERVER_receive_done (client,
-                              GNUNET_OK);
+  GNUNET_SERVICE_client_continue (client);
 }
index 8ee9c41afa863c440b352b658ee2895bff575cbd..01c745a751776e122d10f2902c787c5eca08bd5d 100644 (file)
@@ -50,7 +50,7 @@ struct GNUNET_TESTBED_Barrier *barrier;
 /**
  * Identifier for the shutdown task
  */
-static struct GNUNET_SCHEDULER_Task * shutdown_task;
+static struct GNUNET_SCHEDULER_Task *shutdown_task;
 
 /**
  * Result of this test case
@@ -85,9 +85,9 @@ do_shutdown (void *cls)
  * @param cls the closure given to GNUNET_TESTBED_barrier_init()
  * @param name the name of the barrier
  * @param barrier the barrier handle
- * @param status status of the barrier; GNUNET_OK if the barrier is crossed;
- *   GNUNET_SYSERR upon error
- * @param emsg if the status were to be GNUNET_SYSERR, this parameter has the
+ * @param status status of the barrier; #GNUNET_OK if the barrier is crossed;
+ *   #GNUNET_SYSERR upon error
+ * @param emsg if the status were to be #GNUNET_SYSERR, this parameter has the
  *   error messsage
  */
 static void
@@ -104,17 +104,20 @@ barrier_cb (void *cls,
   switch (status)
   {
   case GNUNET_TESTBED_BARRIERSTATUS_INITIALISED:
-    LOG (GNUNET_ERROR_TYPE_INFO, "Barrier initialised\n");
+    LOG (GNUNET_ERROR_TYPE_INFO,
+         "Barrier initialised\n");
     old_status = status;
     return;
   case GNUNET_TESTBED_BARRIERSTATUS_ERROR:
-    LOG (GNUNET_ERROR_TYPE_ERROR, "Barrier initialisation failed: %s",
+    LOG (GNUNET_ERROR_TYPE_ERROR,
+         "Barrier initialisation failed: %s",
          (NULL == emsg) ? "unknown reason" : emsg);
     barrier = NULL;
     GNUNET_SCHEDULER_shutdown ();
     return;
   case GNUNET_TESTBED_BARRIERSTATUS_CROSSED:
-    LOG (GNUNET_ERROR_TYPE_INFO, "Barrier crossed\n");
+    LOG (GNUNET_ERROR_TYPE_INFO,
+         "Barrier crossed\n");
     if (old_status == GNUNET_TESTBED_BARRIERSTATUS_INITIALISED)
       result = GNUNET_OK;
     barrier = NULL;
@@ -151,13 +154,17 @@ test_master (void *cls,
   GNUNET_assert (NULL == cls);
   if (NULL == peers_)
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failing test due to timeout\n");
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failing test due to timeout\n");
     return;
   }
   GNUNET_assert (NUM_PEERS == num_peers);
   c = GNUNET_TESTBED_run_get_controller_handle (h);
-  barrier = GNUNET_TESTBED_barrier_init (c, TEST_BARRIER_NAME, 100,
-                                         &barrier_cb, NULL);
+  barrier = GNUNET_TESTBED_barrier_init (c,
+                                         TEST_BARRIER_NAME,
+                                         100,
+                                         &barrier_cb,
+                                         NULL);
   shutdown_task =
       GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
                                     (GNUNET_TIME_UNIT_SECONDS,
index 53f70a1c09b2e8072bbb2beaed148ab7b2bd3194..3f2109ecded2df520fbcee99f37e06516103ebaf 100644 (file)
@@ -1298,8 +1298,13 @@ handle_barrier_status (void *cls,
   GNUNET_assert (NULL != barrier->cb);
   if ((GNUNET_YES == barrier->echo) &&
       (GNUNET_TESTBED_BARRIERSTATUS_CROSSED == status))
-    GNUNET_TESTBED_queue_message_ (c, GNUNET_copy_message (&msg->header));
-  barrier->cb (barrier->cls, name, barrier, status, emsg);
+    GNUNET_TESTBED_queue_message_ (c,
+                                   GNUNET_copy_message (&msg->header));
+  barrier->cb (barrier->cls,
+               name,
+               barrier,
+               status,
+               emsg);
   if (GNUNET_TESTBED_BARRIERSTATUS_INITIALISED == status)
     return;           /* just initialised; skip cleanup */
 
index 3761fbbdf567cda658832443f6acb2421fdbf175..1679756a1cb21138277d43feb9b23222e95cc594 100644 (file)
@@ -105,6 +105,9 @@ handle_status (void *cls,
 {
   struct GNUNET_TESTBED_BarrierWaitHandle *h = cls;
 
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Got barrier status %d\n",
+              (int) ntohs (msg->status));
   switch (ntohs (msg->status))
   {
   case GNUNET_TESTBED_BARRIERSTATUS_ERROR:
@@ -206,6 +209,9 @@ GNUNET_TESTBED_barrier_wait (const char *name,
     GNUNET_free (h);
     return NULL;
   }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Waiting on barrier `%s'\n",
+              name);
   h->name = GNUNET_strdup (name);
   h->cb = cb;
   h->cb_cls = cb_cls;
@@ -226,8 +232,8 @@ GNUNET_TESTBED_barrier_wait (const char *name,
                              name_len,
                              GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_WAIT);
   GNUNET_memcpy (msg->name,
-          name,
-          name_len);
+                 name,
+                 name_len);
   GNUNET_MQ_send (h->mq,
                   env);
   return h;
index 3d6f27567cf2fa1fc7900615802ffea16acb5d4d..7c13265d8834229ccd20ec871e80b01d09b5202f 100644 (file)
@@ -295,9 +295,10 @@ GNUNET_MQ_inject_message (struct GNUNET_MQ_Handle *mq,
   }
  done:
   if (GNUNET_NO == handled)
-    LOG (GNUNET_ERROR_TYPE_DEBUG,
-         "No handler for message of type %d\n",
-         ntohs (mh->type));
+    LOG (GNUNET_ERROR_TYPE_INFO,
+         "No handler for message of type %d and size %d\n",
+         ntohs (mh->type),
+         ntohs (mh->size));
 }
 
 
index 9929341f46e408870283a118c52f74c5fd43e325..744adc387dff2f3324e899ba7f09aeb325b7d697 100644 (file)
@@ -136,7 +136,7 @@ struct GNUNET_SERVICE_Handle
   /**
    * Message handlers to use for all clients.
    */
-  const struct GNUNET_MQ_MessageHandler *handlers;
+  struct GNUNET_MQ_MessageHandler *handlers;
 
   /**
    * Closure for @e task.
@@ -1616,12 +1616,24 @@ GNUNET_SERVICE_starT (const char *service_name,
   sh->connect_cb = connect_cb;
   sh->disconnect_cb = disconnect_cb;
   sh->cb_cls = cls;
-  sh->handlers = handlers;
+  if (NULL != handlers)
+  {
+    unsigned int i;
+
+    for (i=0;NULL != handlers[i].cb; i++) ;
+    sh->handlers = GNUNET_new_array (i + 1,
+                                    struct GNUNET_MQ_MessageHandler);
+    GNUNET_memcpy (sh->handlers,
+                   handlers,
+                   i * sizeof (struct GNUNET_MQ_MessageHandler));
+  }
   if (GNUNET_OK != setup_service (sh))
   {
+    GNUNET_free (sh->handlers);
     GNUNET_free (sh);
     return NULL;
   }
+  GNUNET_SERVICE_resume (sh);
   return sh;
 }
 
@@ -1634,7 +1646,13 @@ GNUNET_SERVICE_starT (const char *service_name,
 void
 GNUNET_SERVICE_stoP (struct GNUNET_SERVICE_Handle *srv)
 {
+  struct GNUNET_SERVICE_Client *client;
+
+  GNUNET_SERVICE_suspend (srv);
+  while (NULL != (client = srv->clients_head))
+    GNUNET_SERVICE_client_drop (client);
   teardown_service (srv);
+  GNUNET_free (srv->handlers);
   GNUNET_free (srv);
 }
 
@@ -1736,7 +1754,17 @@ GNUNET_SERVICE_ruN_ (int argc,
   sh.connect_cb = connect_cb;
   sh.disconnect_cb = disconnect_cb;
   sh.cb_cls = cls;
-  sh.handlers = handlers;
+  if (NULL != handlers)
+  {
+    unsigned int i;
+
+    for (i=0;NULL != handlers[i].cb; i++) ;
+    sh.handlers = GNUNET_new_array (i + 1,
+                                    struct GNUNET_MQ_MessageHandler);
+    GNUNET_memcpy (sh.handlers,
+                   handlers,
+                   i * sizeof (struct GNUNET_MQ_MessageHandler));
+  }
   sh.service_name = service_name;
 
   /* setup subsystems */
@@ -1867,7 +1895,7 @@ shutdown:
   }
 #endif
   teardown_service (&sh);
-
+  GNUNET_free (sh.handlers);
   GNUNET_SPEEDUP_stop_ ();
   GNUNET_CONFIGURATION_destroy (cfg);
   GNUNET_free_non_null (logfile);