/**
 * Clean up the transport testing
 * @param tth transport testing handle
 */
void
GNUNET_TRANSPORT_TESTING_done (struct GNUNET_TRANSPORT_TESTING_handle *tth)
{
  struct ConnectingContext *cc = tth->cc_head;
  struct ConnectingContext *ct = NULL;
  struct PeerContext *p = tth->p_head;
  struct PeerContext *t = NULL;

  GNUNET_assert (tth != NULL);

  while (cc != tth->cc_tail)
  {
    ct = cc->next;
    GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "transport-testing",
                     "Developer forgot to cancel connect request %p!\n", cc);
    GNUNET_TRANSPORT_TESTING_connect_peers_cancel (tth, cc);
    cc = ct;
  }

  while (p != NULL)
  {
    t = p->next;
    GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "transport-testing",
                     "Developer forgot to stop peer!\n");
    GNUNET_TRANSPORT_TESTING_stop_peer (tth, p);
    p = t;
  }

  GNUNET_TESTING_system_destroy (tth->tl_system, GNUNET_YES);

  GNUNET_free (tth);
  tth = NULL;
}
/**
 * Task to clean up and shutdown nicely
 *
 * @param cls NULL
 * @param tc the TaskContext from scheduler
 */
static void
shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct MessageQueue *mq_entry;
  uint32_t id;

  shutdown_task_id = NULL;
  LOG_DEBUG ("Shutting down testbed service\n");
  /* cleanup any remaining forwarded operations */
  GST_clear_fopcq ();
  GST_free_lcfq ();
  GST_free_mctxq ();
  GST_free_occq ();
  GST_free_roccq ();
  GST_free_nccq ();
  GST_neighbour_list_clean();
  GST_free_prcq ();
  /* Clear peer list */
  GST_destroy_peers ();
  /* Clear route list */
  GST_route_list_clear ();
  /* Clear GST_slave_list */
  GST_slave_list_clear ();
  /* Clear host list */
  for (id = 0; id < GST_host_list_size; id++)
    if (NULL != GST_host_list[id])
      GNUNET_TESTBED_host_destroy (GST_host_list[id]);
  GNUNET_free_non_null (GST_host_list);
  if (NULL != GST_context)
  {
    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_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 ();
  GST_connection_pool_destroy ();
  GNUNET_TESTBED_operation_queue_destroy_ (GST_opq_openfds);
  GST_opq_openfds = NULL;
  GST_stats_destroy ();
  GST_barriers_destroy ();
  GNUNET_CONFIGURATION_destroy (GST_config);
}
/**
 * Task for shutdown
 *
 * @param cls the testing context
 * @param tc the tast context
 */
static void
do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct TestingContext *test_ctx = cls;
  struct GNUNET_TESTING_Peer *peer;
  unsigned int cnt;

  GNUNET_assert (NULL != test_ctx);
  for (cnt = 0; cnt < NUM_PEERS; cnt++)
  {
    peer = test_ctx->peers[cnt];
    if (NULL == peer)
      continue;
    (void) GNUNET_TESTING_peer_stop (peer);
    GNUNET_TESTING_peer_destroy (peer);
  }
  if (NULL != test_ctx->cfg)
    GNUNET_CONFIGURATION_destroy (test_ctx->cfg);
  if (NULL != test_ctx->system)
    GNUNET_TESTING_system_destroy (test_ctx->system, GNUNET_YES);
  GNUNET_free (test_ctx);
}