/**
 * Destroy a given client peer context
 *
 * @param cp client peer context
 */
static void
destroy_clientpeer (struct ClientPeerContext *cp)
{
  struct PendingMessage *pm;

  cp->destroying = GNUNET_YES;
  if (NULL != cp->th)
  {
    GNUNET_CADET_notify_transmit_ready_cancel (cp->th);
    cp->th = NULL;
  }
  pm = cp->pm_head;
  while (NULL != pm)
  {
    GNUNET_CONTAINER_DLL_remove (cp->pm_head, cp->pm_tail, pm);
    GNUNET_free (pm->msg);
    GNUNET_free (pm);
    pm = cp->pm_head;
  }
  if (NULL != cp->ch)
  {
    GNUNET_CADET_channel_destroy (cp->ch);
    cp->ch = NULL;
  }
  GNUNET_free (cp);
}
Beispiel #2
0
/**
 * Disconnect from cadet services af all peers, call shutdown.
 *
 * @param cls Closure (line number from which termination was requested).
 * @param tc Task Context.
 */
static void
disconnect_cadet_peers (void *cls)
{
  long line = (long) cls;
  unsigned int i;

  disconnect_task = NULL;
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
	      "disconnecting cadet service of peers, called from line %ld\n",
	      line);
  for (i = 0; i < 2; i++)
  {
    GNUNET_TESTBED_operation_done (t_op[i]);
  }
  if (NULL != ch)
  {
    if (NULL != th)
    {
      GNUNET_CADET_notify_transmit_ready_cancel (th);
      th = NULL;
    }
    GNUNET_CADET_channel_destroy (ch);
    ch = NULL;
  }
  if (NULL != incoming_ch)
  {
    if (NULL != incoming_th)
    {
      GNUNET_CADET_notify_transmit_ready_cancel (incoming_th);
      incoming_th = NULL;
    }
    GNUNET_CADET_channel_destroy (incoming_ch);
    incoming_ch = NULL;
  }
  GNUNET_CADET_TEST_cleanup (test_ctx);
  GNUNET_SCHEDULER_shutdown ();
}
Beispiel #3
0
/**
 * Function called whenever an channel is destroyed.  Should clean up
 * any associated state.
 *
 * @param cls closure (set from GNUNET_CADET_connect)
 * @param channel connection to the other end (henceforth invalid)
 * @param channel_ctx place where local state associated
 *                    with the channel is stored
 */
static void
channel_end (void *cls, const struct GNUNET_CADET_Channel *channel,
             void *channel_ctx)
{
  long id = (long) cls;

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "incoming channel closed at peer %ld\n",
              id);
  if (NULL != mth)
  {
    GNUNET_CADET_notify_transmit_ready_cancel (mth);
    mth = NULL;
  }
  if (GNUNET_NO == got_data)
  {
    GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (
                                  GNUNET_TIME_UNIT_SECONDS,
                                  2),
                                  &do_connect, NULL);
  }
}
Beispiel #4
0
/**
 * Task to gather all statistics.
 *
 * @param cls Closure (NULL).
 */
static void
gather_stats_and_exit (void *cls)
{
  long l = (long) cls;

  disconnect_task = NULL;
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
	      "gathering statistics from line %d\n",
	      (int) l);
  if (NULL != ch)
  {
    if (NULL != th)
    {
      GNUNET_CADET_notify_transmit_ready_cancel (th);
      th = NULL;
    }
    GNUNET_CADET_channel_destroy (ch);
    ch = NULL;
  }
  stats_op = GNUNET_TESTBED_get_statistics (peers_running, testbed_peers,
                                            "cadet", NULL,
                                            stats_iterator, stats_cont, cls);
}
Beispiel #5
0
/**
 * Function is called whenever a message is received.
 *
 * @param cls closure (set from GNUNET_CADET_connect, peer number)
 * @param channel connection to the other end
 * @param channel_ctx place to store local state associated with the channel
 * @param message the actual message
 * @return GNUNET_OK to keep the connection open,
 *         GNUNET_SYSERR to close it (signal serious error)
 */
int
data_callback (void *cls, struct GNUNET_CADET_Channel *channel,
               void **channel_ctx,
               const struct GNUNET_MessageHeader *message)
{
  struct GNUNET_CADET_TransmitHandle **pth;
  long client = (long) cls;
  long expected_target_client;
  uint32_t *data;
  uint32_t payload;
  unsigned int counter;

  ok++;
  counter = get_expected_target () == client ? data_received : ack_received;

  GNUNET_CADET_receive_done (channel);

  if ((ok % 10) == 0)
  {
    if (NULL != disconnect_task)
    {
      GNUNET_log (GNUNET_ERROR_TYPE_INFO, " reschedule timeout\n");
      GNUNET_SCHEDULER_cancel (disconnect_task);
      disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME,
                                                      &gather_stats_and_exit,
                                                      (void *) __LINE__);
    }
  }

  switch (client)
  {
  case 0L:
    GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Root client got a message!\n");
    GNUNET_assert (channel == ch);
    pth = &th;
    break;
  case 1L:
  case 4L:
    GNUNET_assert (client == peers_requested - 1);
    GNUNET_assert (channel == incoming_ch);
    pth = &incoming_th;
    GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Leaf client %ld got a message.\n",
                client);
    break;
  default:
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Client %ld not valid.\n", client);
    GNUNET_assert (0);
  }
  GNUNET_log (GNUNET_ERROR_TYPE_INFO, " ok: (%d/%d)\n", ok, ok_goal);
  data = (uint32_t *) &message[1];
  payload = ntohl (*data);
  if (payload == counter)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_INFO, " payload as expected: %u\n", payload);
  }
  else
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, " payload %u, expected: %u\n",
                payload, counter);
  }
  expected_target_client = get_expected_target ();

  if (GNUNET_NO == initialized)
  {
    initialized = GNUNET_YES;
    start_time = GNUNET_TIME_absolute_get ();
    if (SPEED == test)
    {
      GNUNET_assert (peers_requested - 1 == client);
      data_job = GNUNET_SCHEDULER_add_now (&data_task, NULL);
      return GNUNET_OK;
    }
  }

  counter++;
  if (client == expected_target_client) /* Normally 4 */
  {
    data_received++;
    GNUNET_log (GNUNET_ERROR_TYPE_INFO, " received data %u\n", data_received);
    if (SPEED != test || (ok_goal - 2) == ok)
    {
      /* Send ACK */
      GNUNET_assert (NULL == *pth);
      *pth = GNUNET_CADET_notify_transmit_ready (channel, GNUNET_NO,
                                                 GNUNET_TIME_UNIT_FOREVER_REL,
                                                 size_payload + ack_sent,
                                                 &tmt_rdy, (void *) client);
      return GNUNET_OK;
    }
    else
    {
      if (data_received < TOTAL_PACKETS)
        return GNUNET_OK;
    }
  }
  else /* Normally 0 */
  {
    if (SPEED_ACK == test || SPEED == test)
    {
      ack_received++;
      GNUNET_log (GNUNET_ERROR_TYPE_INFO, " received ack %u\n", ack_received);
      /* send more data */
      GNUNET_assert (NULL == *pth);
      *pth = GNUNET_CADET_notify_transmit_ready (channel, GNUNET_NO,
                                                 GNUNET_TIME_UNIT_FOREVER_REL,
                                                 size_payload + data_sent,
                                                 &tmt_rdy, (void *) client);
      if (ack_received < TOTAL_PACKETS && SPEED != test)
        return GNUNET_OK;
      if (ok == 2 && SPEED == test)
        return GNUNET_OK;
      show_end_data();
    }
    if (test == P2P_SIGNAL)
    {
      if (NULL != incoming_th)
      {
        GNUNET_CADET_notify_transmit_ready_cancel (incoming_th);
        incoming_th = NULL;
      }
      GNUNET_CADET_channel_destroy (incoming_ch);
      incoming_ch = NULL;
    }
    else
    {
      if (NULL != th)
      {
        GNUNET_CADET_notify_transmit_ready_cancel (th);
        th = NULL;
      }
      GNUNET_CADET_channel_destroy (ch);
      ch = NULL;
    }
  }

  return GNUNET_OK;
}