/**
 * Transmit pending requests via the stream.
 *
 * @param sh stream to process
 */
static void
transmit_pending (struct StreamHandle *sh)
{
  struct StreamQueryMessage sqm;
  struct GSF_StreamRequest *sr;

  if (NULL != sh->wh)
    return;
  sr = sh->pending_head;
  if (NULL == sr)
    return;
  GNUNET_CONTAINER_DLL_remove (sh->pending_head,
			       sh->pending_tail,
			       sr);
  GNUNET_CONTAINER_multihashmap_put (sh->waiting_map,
				     &sr->query,
				     sr,
				     GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
	      "Sending query via stream to %s\n",
	      GNUNET_i2s (&sh->target));
  sr->was_transmitted = GNUNET_YES;
  sqm.header.size = htons (sizeof (sqm));
  sqm.header.type = htons (GNUNET_MESSAGE_TYPE_FS_STREAM_QUERY);
  sqm.type = htonl (sr->type);
  sqm.query = sr->query;
  sh->wh = GNUNET_STREAM_write (sh->stream,
				&sqm, sizeof (sqm),
				GNUNET_TIME_UNIT_FOREVER_REL,
				&query_write_continuation,
				sh);
}
Exemplo n.º 2
0
/**
 * Task for calling STREAM_write with a chunk of random data
 *
 * @param cls the peer data entity
 * @param tc the task context
 */
static void
stream_write_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct PeerData *pdata = cls;
  size_t write_amount;

  if (GNUNET_SCHEDULER_NO_TASK != abort_task)
  {
    GNUNET_SCHEDULER_cancel (abort_task);
    abort_task = 
      GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
                                    (GNUNET_TIME_UNIT_SECONDS, 300), &do_abort,
                                    NULL);
  }
  write_task = GNUNET_SCHEDULER_NO_TASK;
  prof_start_time = GNUNET_TIME_absolute_get ();
  pdata->bytes_wrote = 0;
  pdata->packets_wrote = 0;
  write_amount = MAX_PACKETS * payload_size[payload_size_index];
  if (write_amount > DATA_SIZE)
    write_amount = DATA_SIZE;
  reset_read = GNUNET_YES;
  pdata->io_write_handle = GNUNET_STREAM_write (pdata->socket, data,
                                                write_amount,
						GNUNET_TIME_UNIT_FOREVER_REL,
						&write_completion, pdata);
  GNUNET_assert (NULL != pdata->io_write_handle);
}
Exemplo n.º 3
0
/**
 * The write completion function; called upon writing some data to stream or
 * upon error
 *
 * @param cls the closure from GNUNET_STREAM_write/read
 * @param status the status of the stream at the time this function is called
 * @param size the number of bytes read or written
 */
static void
write_completion (void *cls,
                  enum GNUNET_STREAM_Status status,
                  size_t size)
{
    struct PeerData *peer;

    peer = (struct PeerData *) cls;
    GNUNET_assert (GNUNET_STREAM_OK == status);
    GNUNET_assert (size <= DATA_SIZE);
    peer->bytes_wrote += size;

    if (peer->bytes_wrote < DATA_SIZE) /* Have more data to send */
    {
        peer->io_write_handle =
            GNUNET_STREAM_write (peer->socket,
                                 ((void *) data) + peer->bytes_wrote,
                                 sizeof (data) - peer->bytes_wrote,
                                 GNUNET_TIME_relative_multiply
                                 (GNUNET_TIME_UNIT_SECONDS, 5),
                                 &write_completion,
                                 cls);
        GNUNET_assert (NULL != peer->io_write_handle);
    }
    else
    {
        LOG (GNUNET_ERROR_TYPE_DEBUG, "Writing successfully finished\n");
        result = GNUNET_OK;
        GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
    }
}
/**
 * Process a datum that was stored in the datastore.
 *
 * @param cls closure with the struct StreamClient which sent the query
 * @param key key for the content
 * @param size number of bytes in data
 * @param data content stored
 * @param type type of the content
 * @param priority priority of the content
 * @param anonymity anonymity-level for the content
 * @param expiration expiration time for the content
 * @param uid unique identifier for the datum;
 *        maybe 0 if no unique identifier is available
 */
static void 
handle_datastore_reply (void *cls,
			const struct GNUNET_HashCode * key,
			size_t size, const void *data,
			enum GNUNET_BLOCK_Type type,
			uint32_t priority,
			uint32_t anonymity,
			struct GNUNET_TIME_Absolute
			expiration, uint64_t uid)
{
  struct StreamClient *sc = cls;
  size_t msize = size + sizeof (struct StreamReplyMessage);
  char buf[msize] GNUNET_ALIGN;
  struct StreamReplyMessage *srm = (struct StreamReplyMessage *) buf;

  sc->qe = NULL;
  if (GNUNET_BLOCK_TYPE_FS_ONDEMAND == type)
  {
    if (GNUNET_OK !=
	GNUNET_FS_handle_on_demand_block (key,
					  size, data, type,
					  priority, anonymity,
					  expiration, uid,
					  &handle_datastore_reply,
					  sc))
    {
      continue_reading (sc);
    }
    return;
  }
  if (msize > GNUNET_SERVER_MAX_MESSAGE_SIZE)
  {
    GNUNET_break (0);
    continue_reading (sc);
    return;
  }
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
	      "Starting transmission of %u byte reply via stream\n",
	      (unsigned int) size);
  srm->header.size = htons ((uint16_t) msize);
  srm->header.type = htons (GNUNET_MESSAGE_TYPE_FS_STREAM_REPLY);
  srm->type = htonl (type);
  srm->expiration = GNUNET_TIME_absolute_hton (expiration);
  memcpy (&srm[1], data, size);
  sc->reply_size = msize;
  sc->wh = GNUNET_STREAM_write (sc->socket,
				buf, msize,
				GNUNET_TIME_UNIT_FOREVER_REL,
				&write_continuation,
				sc);
  if (NULL == sc->wh)
  {
    terminate_stream (sc);
    return;
  }
}
Exemplo n.º 5
0
/**
 * Task for calling STREAM_write
 *
 * @param cls the peer data entity
 * @param tc the task context
 */
static void
stream_write_task (void *cls,
                   const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct PeerData *peer = cls;
  
  peer->io_write_handle = 
    GNUNET_STREAM_write (peer->socket,
                         (void *) data,
                         strlen(data) - peer->bytes_wrote,
                         GNUNET_TIME_relative_multiply
                         (GNUNET_TIME_UNIT_SECONDS, 5),
                         &write_completion,
                         peer);
 
  GNUNET_assert (NULL != peer->io_write_handle);
 }
Exemplo n.º 6
0
/**
 * Task for calling STREAM_write with a chunk of random data
 *
 * @param cls the peer data entity
 * @param tc the task context
 */
static void
stream_write_task (void *cls,
                   const struct GNUNET_SCHEDULER_TaskContext *tc)
{
    struct PeerData *peer=cls;
    unsigned int count;

    write_task = GNUNET_SCHEDULER_NO_TASK;
    for (count=0; count < DATA_SIZE / 4; count++)
    {
        data[count]=GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
                                              UINT32_MAX);
    }
    LOG (GNUNET_ERROR_TYPE_DEBUG, "Generation of random data complete\n");
    peer->io_write_handle = GNUNET_STREAM_write (peer->socket,
                            data,
                            sizeof (data),
                            GNUNET_TIME_relative_multiply
                            (GNUNET_TIME_UNIT_SECONDS, 10),
                            &write_completion,
                            peer);
    GNUNET_assert (NULL != peer->io_write_handle);
}
Exemplo n.º 7
0
/**
 * The write completion function; called upon writing some data to stream or
 * upon error
 *
 * @param cls the closure from GNUNET_STREAM_write/read
 * @param status the status of the stream at the time this function is called
 * @param size the number of bytes written
 */
static void 
write_completion (void *cls, enum GNUNET_STREAM_Status status, size_t size)
{
  struct PeerData *pdata = cls;
  double throughput;
  double prof_time_sec;
  unsigned int packets_wrote;

  if (GNUNET_STREAM_OK != status)
  {
    GNUNET_SCHEDULER_cancel (abort_task);
    abort_task = GNUNET_SCHEDULER_add_now (&do_abort, NULL);
    return;
  }
  GNUNET_assert (size <= DATA_SIZE);
  packets_wrote = (size + payload_size[payload_size_index] - 1)
      / payload_size[payload_size_index];
  pdata->bytes_wrote += size;
  for (;packets_wrote > 0; packets_wrote--)
  {    
    update_meter (meter);
    pdata->packets_wrote++;
  }
  if (pdata->packets_wrote < MAX_PACKETS) /* Have more data to send */
  {
    size_t write_amount;
    
    if (GNUNET_SCHEDULER_NO_TASK != abort_task)
    {
      GNUNET_SCHEDULER_cancel (abort_task);
      abort_task = 
          GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
                                        (GNUNET_TIME_UNIT_SECONDS, 300), &do_abort,
                                    NULL);
    }
    write_amount = (MAX_PACKETS - pdata->packets_wrote) *
        payload_size[payload_size_index];
    if (write_amount > DATA_SIZE)
      write_amount = DATA_SIZE;
    reset_read = GNUNET_YES;
    pdata->io_write_handle = GNUNET_STREAM_write (pdata->socket, data,
                                                  write_amount,
                                                  GNUNET_TIME_UNIT_FOREVER_REL,
                                                  &write_completion, pdata);
    GNUNET_assert (NULL != pdata->io_write_handle);
  }
  else
  {
    free_meter (meter);
    meter = NULL;
    prof_time = GNUNET_TIME_absolute_get_duration (prof_start_time);
    prof_time_sec = (((double) prof_time.rel_value)/ ((double) 1000));
    throughput = ((float) pdata->bytes_wrote) / prof_time_sec;
    PRINTF ("Throughput %.2f kB/sec\n", throughput / 1000.00);
    switch (result)
    {
    case INIT:
      result = UPLINK_OK;
      GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == read_task);
      GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == write_task);
      pdata->bytes_read = 0;
      pdata->packets_read = 0;
      meter = create_meter (MAX_PACKETS, "Testing Downlink\n", GNUNET_YES);
      read_task = GNUNET_SCHEDULER_add_now (&stream_read_task, &peer_data[0]);
      write_task = GNUNET_SCHEDULER_add_now (&stream_write_task, &peer_data[1]);
      break;
    case UPLINK_OK:
      result = DOWNLINK_OK;
      GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
      break;
    case DOWNLINK_OK:
      GNUNET_assert (0);
    }
  }
}