static void
end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  die_task = NULL;

  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Fail! Stopping peers\n");


  if (send_task != NULL)
    GNUNET_SCHEDULER_cancel (send_task);

  if (cc != NULL)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Fail! Could not connect peers\n"));
    GNUNET_TRANSPORT_TESTING_connect_peers_cancel (tth, cc);
    cc = NULL;
  }

  if (th != NULL)
    GNUNET_TRANSPORT_notify_transmit_ready_cancel (th);
  else
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Peer were not ready to send data\n"));

  if (s_started == GNUNET_NO)
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Peers were not started \n"));
  else
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Peers were started \n"));

  if (s_connected == GNUNET_NO)
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Peer were not connected\n"));
  else
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Peer were connected\n"));

  if (s_sending == GNUNET_NO)
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Peer were not ready to send data\n"));
  else
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Peer were ready to send data\n"));

  th = NULL;

  if (NULL != vmc_p1)
  {
    GNUNET_TRANSPORT_monitor_validation_entries_cancel (vmc_p1);
    vmc_p1 = NULL;
  }
  if (NULL != vmc_p2)
  {
    GNUNET_TRANSPORT_monitor_validation_entries_cancel (vmc_p2);
    vmc_p2 = NULL;
  }

  if (p1 != NULL)
    GNUNET_TRANSPORT_TESTING_stop_peer (tth, p1);
  else
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Peer 1 was not started\n"));
  if (p2 != NULL)
    GNUNET_TRANSPORT_TESTING_stop_peer (tth, p2);
  else
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Peer 2 was not started\n"));

  ok = GNUNET_SYSERR;
}
/**
 * Function called with responses from the service.
 *
 * @param cls our `struct GNUNET_TRANSPORT_ValidationMonitoringContext *`
 * @param msg NULL on timeout or error, otherwise presumably a
 *        message with the human-readable address
 */
static void
val_response_processor (void *cls,
                        const struct GNUNET_MessageHeader *msg)
{
  struct GNUNET_TRANSPORT_ValidationMonitoringContext *val_ctx = cls;
  struct ValidationIterateResponseMessage *vr_msg;
  struct GNUNET_HELLO_Address *address;
  const char *addr;
  const char *transport_name;
  size_t size;
  size_t tlen;
  size_t alen;

  if (NULL == msg)
  {
    if (val_ctx->one_shot)
    {
      /* Disconnect */
      val_ctx->cb (val_ctx->cb_cls, NULL,
          GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO_ABS,
          GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TRANSPORT_VS_TIMEOUT);
      GNUNET_TRANSPORT_monitor_validation_entries_cancel (val_ctx);
    }
    else
    {
      reconnect_val_ctx (val_ctx);
    }
    return;
  }
  size = ntohs (msg->size);
  GNUNET_break (ntohs (msg->type) ==
      GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_VALIDATION_RESPONSE);

  if (size == sizeof (struct GNUNET_MessageHeader))
  {
    /* Done! */
    if (val_ctx->one_shot)
    {
      val_ctx->cb (val_ctx->cb_cls, NULL,
          GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO_ABS,
          GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TRANSPORT_VS_NONE);
      GNUNET_TRANSPORT_monitor_validation_entries_cancel (val_ctx);
    }
    else
    {
      reconnect_val_ctx (val_ctx);
    }
    return;
  }

  if ((size < sizeof (struct ValidationIterateResponseMessage)) ||
      (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_VALIDATION_RESPONSE))
  {
    GNUNET_break (0);
    if (val_ctx->one_shot)
    {
      val_ctx->cb (val_ctx->cb_cls, NULL,
          GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO_ABS,
          GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TRANSPORT_VS_NONE);
      GNUNET_TRANSPORT_monitor_validation_entries_cancel (val_ctx);
    }
    else
    {
      reconnect_val_ctx (val_ctx);
    }
    return;
  }

  vr_msg = (struct ValidationIterateResponseMessage *) msg;
  tlen = ntohl (vr_msg->pluginlen);
  alen = ntohl (vr_msg->addrlen);

  if (size != sizeof (struct ValidationIterateResponseMessage) + tlen + alen)
  {
    GNUNET_break (0);
    if (val_ctx->one_shot)
    {
      val_ctx->cb (val_ctx->cb_cls, NULL,
          GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO_ABS,
          GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TRANSPORT_VS_NONE);
      GNUNET_TRANSPORT_monitor_validation_entries_cancel (val_ctx);
    }
    else
    {
      reconnect_val_ctx (val_ctx);
    }
    return;
  }
  if (0 == tlen)
  {
    GNUNET_break (0); /* This must not happen: address without plugin */
    return;
  }
  addr = (const char *) &vr_msg[1];
  transport_name = &addr[alen];
  
  if (transport_name[tlen - 1] != '\0')
  {
    /* Corrupt plugin name */
    GNUNET_break (0);
    if (val_ctx->one_shot)
    {
      val_ctx->cb (val_ctx->cb_cls,
		   NULL,
		   GNUNET_TIME_UNIT_ZERO_ABS,
		   GNUNET_TIME_UNIT_ZERO_ABS,
		   GNUNET_TIME_UNIT_ZERO_ABS,
		   GNUNET_TRANSPORT_VS_NONE);
      GNUNET_TRANSPORT_monitor_validation_entries_cancel (val_ctx);
    }
    else
    {
      reconnect_val_ctx (val_ctx);
    }
    return;
  }
  
  /* notify client */
  address = GNUNET_HELLO_address_allocate (&vr_msg->peer,
					   transport_name,
					   addr, alen,
					   ntohl (vr_msg->local_address_info));
  val_ctx->cb (val_ctx->cb_cls,
	       address,
	       GNUNET_TIME_absolute_ntoh (vr_msg->last_validation),
	       GNUNET_TIME_absolute_ntoh (vr_msg->valid_until),
	       GNUNET_TIME_absolute_ntoh (vr_msg->next_validation),
	       ntohl(vr_msg->state));
  GNUNET_HELLO_address_free (address);
  /* expect more replies */
  GNUNET_CLIENT_receive (val_ctx->client,
                         &val_response_processor,
                         val_ctx,
                         GNUNET_TIME_absolute_get_remaining (val_ctx->timeout));
}