示例#1
0
/**
 * Notification of FS that a search probe has made progress.
 * This function is used INSTEAD of the client's event handler
 * for downloads where the #GNUNET_FS_DOWNLOAD_IS_PROBE flag is set.
 *
 * @param cls closure, always NULL (!), actual closure
 *        is in the client-context of the info struct
 * @param info details about the event, specifying the event type
 *        and various bits about the event
 * @return client-context (for the next progress call
 *         for this operation; should be set to NULL for
 *         SUSPEND and STOPPED events).  The value returned
 *         will be passed to future callbacks in the respective
 *         field in the `struct GNUNET_FS_ProgressInfo`.
 */
void *
GNUNET_FS_search_probe_progress_ (void *cls,
                                  const struct GNUNET_FS_ProgressInfo *info)
{
  struct GNUNET_FS_SearchResult *sr = info->value.download.cctx;
  struct GNUNET_TIME_Relative dur;

  switch (info->status)
  {
  case GNUNET_FS_STATUS_DOWNLOAD_START:
    /* ignore */
    break;
  case GNUNET_FS_STATUS_DOWNLOAD_RESUME:
    /* probes should never be resumed */
    GNUNET_assert (0);
    break;
  case GNUNET_FS_STATUS_DOWNLOAD_SUSPEND:
    /* probes should never be suspended */
    GNUNET_break (0);
    break;
  case GNUNET_FS_STATUS_DOWNLOAD_PROGRESS:
    /* ignore */
    break;
  case GNUNET_FS_STATUS_DOWNLOAD_ERROR:
    if (GNUNET_SCHEDULER_NO_TASK != sr->probe_cancel_task)
    {
      GNUNET_SCHEDULER_cancel (sr->probe_cancel_task);
      sr->probe_cancel_task = GNUNET_SCHEDULER_NO_TASK;
    }
    sr->probe_cancel_task =
        GNUNET_SCHEDULER_add_delayed (sr->remaining_probe_time,
                                      &probe_failure_handler, sr);
    break;
  case GNUNET_FS_STATUS_DOWNLOAD_COMPLETED:
    if (GNUNET_SCHEDULER_NO_TASK != sr->probe_cancel_task)
    {
      GNUNET_SCHEDULER_cancel (sr->probe_cancel_task);
      sr->probe_cancel_task = GNUNET_SCHEDULER_NO_TASK;
    }
    sr->probe_cancel_task =
        GNUNET_SCHEDULER_add_now (&probe_success_handler, sr);
    break;
  case GNUNET_FS_STATUS_DOWNLOAD_STOPPED:
    if (GNUNET_SCHEDULER_NO_TASK != sr->probe_cancel_task)
    {
      GNUNET_SCHEDULER_cancel (sr->probe_cancel_task);
      sr->probe_cancel_task = GNUNET_SCHEDULER_NO_TASK;
    }
    sr = NULL;
    break;
  case GNUNET_FS_STATUS_DOWNLOAD_ACTIVE:
    if (GNUNET_SCHEDULER_NO_TASK == sr->probe_cancel_task)
    {
      sr->probe_active_time = GNUNET_TIME_absolute_get ();
      sr->probe_cancel_task =
        GNUNET_SCHEDULER_add_delayed (sr->remaining_probe_time,
                                      &probe_failure_handler, sr);
    }
    break;
  case GNUNET_FS_STATUS_DOWNLOAD_INACTIVE:
    if (GNUNET_SCHEDULER_NO_TASK != sr->probe_cancel_task)
    {
      GNUNET_SCHEDULER_cancel (sr->probe_cancel_task);
      sr->probe_cancel_task = GNUNET_SCHEDULER_NO_TASK;
    }
    dur = GNUNET_TIME_absolute_get_duration (sr->probe_active_time);
    sr->remaining_probe_time =
        GNUNET_TIME_relative_subtract (sr->remaining_probe_time, dur);
    if (0 == sr->remaining_probe_time.rel_value_us)
      sr->probe_cancel_task =
        GNUNET_SCHEDULER_add_now (&probe_failure_handler, sr);
    GNUNET_FS_search_result_sync_ (sr);
    break;
  default:
    GNUNET_break (0);
    return NULL;
  }
  return sr;
}
示例#2
0
static struct GNUNET_TIME_Relative
get_delay (struct TrafficGenerator *tg)
{
  struct GNUNET_TIME_Relative delay;
  struct GNUNET_TIME_Relative time_delta;
  long long int cur_rate;
  long long int delta_rate;

  delay.rel_value_us = 0;

  /* Calculate the current transmission rate based on the type of traffic */
  switch (tg->type) {
    case GNUNET_ATS_TEST_TG_CONSTANT:
      if (UINT32_MAX == tg->base_rate)
        return GNUNET_TIME_UNIT_ZERO;
      cur_rate = tg->base_rate;
      break;
    case GNUNET_ATS_TEST_TG_LINEAR:
      time_delta = GNUNET_TIME_absolute_get_duration(tg->time_start);
      /* Calculate point of time in the current period */
      time_delta.rel_value_us = time_delta.rel_value_us % tg->duration_period.rel_value_us;
      delta_rate = ((double) time_delta.rel_value_us  / tg->duration_period.rel_value_us) *
          (tg->max_rate - tg->base_rate);
      if ((tg->max_rate < tg->base_rate) && ((tg->max_rate - tg->base_rate) > tg->base_rate))
      {
        /* This will cause an underflow */
        GNUNET_break (0);
      }
      cur_rate = tg->base_rate + delta_rate;
      break;
    case GNUNET_ATS_TEST_TG_RANDOM:
      cur_rate = tg->base_rate + GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
          tg->max_rate - tg->base_rate);
      break;
    case GNUNET_ATS_TEST_TG_SINUS:
      time_delta = GNUNET_TIME_absolute_get_duration(tg->time_start);
      /* Calculate point of time in the current period */
      time_delta.rel_value_us = time_delta.rel_value_us % tg->duration_period.rel_value_us;
      if ((tg->max_rate - tg->base_rate) > tg->base_rate)
      {
        /* This will cause an underflow for second half of sinus period,
         * will be detected in general when experiments are loaded */
        GNUNET_break (0);
      }
      delta_rate = (tg->max_rate - tg->base_rate) *
          sin ( (2 * M_PI) / ((double) tg->duration_period.rel_value_us) * time_delta.rel_value_us);
      cur_rate = tg->base_rate + delta_rate;
      break;
    default:
      return delay;
      break;
  }

  if (cur_rate < 0)
  {
    cur_rate = 1;
  }
  /* Calculate the delay for the next message based on the current delay  */
  delay.rel_value_us =  GNUNET_TIME_UNIT_SECONDS.rel_value_us * TEST_MESSAGE_SIZE / cur_rate;

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
      "Current rate is %u, calculated delay is %u \n",
      cur_rate, delay.rel_value_us);
  return delay;
}
示例#3
0
static void *
progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event)
{
  switch (event->status)
  {
  case GNUNET_FS_STATUS_PUBLISH_PROGRESS:
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
		"Publish is progressing (%llu/%llu at level %u off %llu)...\n",
		(unsigned long long) event->value.publish.completed,
		(unsigned long long) event->value.publish.size,
		event->value.publish.specifics.progress.depth,
		(unsigned long long) event->value.publish.specifics.
		progress.offset);
    break;
  case GNUNET_FS_STATUS_PUBLISH_PROGRESS_DIRECTORY:
    break;
  case GNUNET_FS_STATUS_PUBLISH_COMPLETED:
    printf ("Publishing complete, %llu kbps.\n",
            (unsigned long long) (FILESIZE * 1000000LL /
                                  (1 +
                                   GNUNET_TIME_absolute_get_duration
                                   (start).rel_value_us) / 1024));
    start = GNUNET_TIME_absolute_get ();
    unindex = GNUNET_FS_unindex_start (fs, fn, "unindex");
    GNUNET_assert (unindex != NULL);
    break;
  case GNUNET_FS_STATUS_UNINDEX_COMPLETED:
    printf ("Unindex complete,  %llu kbps.\n",
            (unsigned long long) (FILESIZE * 1000000LL /
                                  (1 +
                                   GNUNET_TIME_absolute_get_duration
                                   (start).rel_value_us) / 1024));
    GNUNET_SCHEDULER_add_now (&abort_unindex_task, NULL);
    break;
  case GNUNET_FS_STATUS_UNINDEX_PROGRESS:
    consider_restart (event->status);
    GNUNET_assert (unindex == event->value.unindex.uc);
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
		"Unindex is progressing (%llu/%llu at level %u off %llu)...\n",
		(unsigned long long) event->value.unindex.completed,
		(unsigned long long) event->value.unindex.size,
		event->value.unindex.specifics.progress.depth,
		(unsigned long long) event->value.unindex.specifics.
		progress.offset);
    break;
  case GNUNET_FS_STATUS_PUBLISH_SUSPEND:
    if (event->value.publish.pc == publish)
      publish = NULL;
    break;
  case GNUNET_FS_STATUS_PUBLISH_RESUME:
    if (NULL == publish)
    {
      publish = event->value.publish.pc;
      return "publish-context";
    }
    break;
  case GNUNET_FS_STATUS_UNINDEX_SUSPEND:
    GNUNET_assert (event->value.unindex.uc == unindex);
    unindex = NULL;
    break;
  case GNUNET_FS_STATUS_UNINDEX_RESUME:
    GNUNET_assert (NULL == unindex);
    unindex = event->value.unindex.uc;
    return "unindex";
  case GNUNET_FS_STATUS_PUBLISH_ERROR:
    FPRINTF (stderr, "Error publishing file: %s\n",
             event->value.publish.specifics.error.message);
    GNUNET_break (0);
    GNUNET_SCHEDULER_add_now (&abort_publish_task, NULL);
    break;
  case GNUNET_FS_STATUS_UNINDEX_ERROR:
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
		"Error unindexing file: %s\n",
		event->value.unindex.specifics.error.message);
    GNUNET_SCHEDULER_add_now (&abort_unindex_task, NULL);
    break;
  case GNUNET_FS_STATUS_PUBLISH_START:
    GNUNET_assert (0 == strcmp ("publish-context", event->value.publish.cctx));
    GNUNET_assert (NULL == event->value.publish.pctx);
    GNUNET_assert (FILESIZE == event->value.publish.size);
    GNUNET_assert (0 == event->value.publish.completed);
    GNUNET_assert (1 == event->value.publish.anonymity);
    break;
  case GNUNET_FS_STATUS_PUBLISH_STOPPED:
    GNUNET_assert (publish == event->value.publish.pc);
    GNUNET_assert (FILESIZE == event->value.publish.size);
    GNUNET_assert (1 == event->value.publish.anonymity);
    GNUNET_FS_stop (fs);
    fs = NULL;
    break;
  case GNUNET_FS_STATUS_UNINDEX_START:
    consider_restart (event->status);
    GNUNET_assert (unindex == NULL);
    GNUNET_assert (0 == strcmp ("unindex", event->value.unindex.cctx));
    GNUNET_assert (0 == strcmp (fn, event->value.unindex.filename));
    GNUNET_assert (FILESIZE == event->value.unindex.size);
    GNUNET_assert (0 == event->value.unindex.completed);
    break;
  case GNUNET_FS_STATUS_UNINDEX_STOPPED:
    GNUNET_assert (unindex == event->value.unindex.uc);
    GNUNET_SCHEDULER_add_now (&abort_publish_task, NULL);
    break;
  default:
    printf ("Unexpected event: %d\n", event->status);
    break;
  }
  return NULL;
}
/**
 * Function called when the transport service is ready to receive a
 * message for the respective peer
 *
 * @param cls neighbour to use message from
 * @param size number of bytes we can transmit
 * @param buf where to copy the message
 * @return number of bytes transmitted
 */
static size_t
transmit_ready (void *cls,
                size_t size,
                void *buf)
{
  struct Neighbour *n = cls;
  struct NeighbourMessageEntry *m;
  size_t ret;
  char *cbuf;
  struct GNUNET_TIME_Relative delay;
  struct GNUNET_TIME_Relative overdue;

  n->th = NULL;
  m = n->message_head;
  if (NULL == m)
  {
    GNUNET_break (0);
    return 0;
  }
  GNUNET_CONTAINER_DLL_remove (n->message_head,
                               n->message_tail,
                               m);
  n->queue_size--;
  if (NULL == buf)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "Transmission of message of type %u and size %u failed\n",
                (unsigned int)
                ntohs (((struct GNUNET_MessageHeader *) &m[1])->type),
                (unsigned int) m->size);
    GNUNET_free (m);
    process_queue (n);
    return 0;
  }
  delay = GNUNET_TIME_absolute_get_duration (m->submission_time);
  overdue = GNUNET_TIME_absolute_get_duration (m->deadline);
  cbuf = buf;
  GNUNET_assert (size >= m->size);
  memcpy (cbuf,
          &m[1],
          m->size);
  ret = m->size;
  if (overdue.rel_value_us > GNUNET_CONSTANTS_LATENCY_WARN.rel_value_us)
    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                "Copied overdue message of type %u and size %u into transport buffer for `%s' with delay of %s\n",
                (unsigned int)
                ntohs (((struct GNUNET_MessageHeader *) &m[1])->type),
                (unsigned int) ret,
                GNUNET_i2s (&n->peer),
                GNUNET_STRINGS_relative_time_to_string (delay,
                                                        GNUNET_YES));
  else
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "Copied message of type %u and size %u into transport buffer for `%s' with delay of %s\n",
                (unsigned int)
                ntohs (((struct GNUNET_MessageHeader *) &m[1])->type),
                (unsigned int) ret,
                GNUNET_i2s (&n->peer),
                GNUNET_STRINGS_relative_time_to_string (delay,
                                                        GNUNET_YES));
  GNUNET_free (m);
  n->has_excess_bandwidth = GNUNET_NO;
  process_queue (n);
  GNUNET_STATISTICS_update (GSC_stats,
                            gettext_noop
                            ("# encrypted bytes given to transport"), ret,
                            GNUNET_NO);
  return ret;
}
/**
 * We've received a PONG.  Check if it matches a pending PING and
 * mark the respective address as confirmed.
 *
 * @param sender peer sending the PONG
 * @param hdr the PONG
 */
void
GST_validation_handle_pong (const struct GNUNET_PeerIdentity *sender,
                            const struct GNUNET_MessageHeader *hdr)
{
  const struct TransportPongMessage *pong;
  struct ValidationEntry *ve;
  const char *tname;
  const char *addr;
  size_t addrlen;
  size_t slen;
  size_t size;
  struct GNUNET_HELLO_Message *hello;
  struct GNUNET_HELLO_Address address;

  if (ntohs (hdr->size) < sizeof (struct TransportPongMessage))
  {
    GNUNET_break_op (0);
    return;
  }
  GNUNET_STATISTICS_update (GST_stats,
                            gettext_noop ("# PONG messages received"), 1,
                            GNUNET_NO);

  pong = (const struct TransportPongMessage *) hdr;
  tname = (const char *) &pong[1];
  size = ntohs (hdr->size) - sizeof (struct TransportPongMessage);
  addr = memchr (tname, '\0', size);
  if (NULL == addr)
  {
    GNUNET_break_op (0);
    return;
  }
  addr++;
  slen = strlen (tname) + 1;
  addrlen = size - slen;
  address.peer = *sender;
  address.address = addr;
  address.address_length = addrlen;
  address.transport_name = tname;
  ve = find_validation_entry (NULL, &address);
  if ((NULL == ve) || (ve->expecting_pong == GNUNET_NO))
  {
    GNUNET_STATISTICS_update (GST_stats,
                              gettext_noop
                              ("# PONGs dropped, no matching pending validation"),
                              1, GNUNET_NO);
    return;
  }
  /* now check that PONG is well-formed */
  if (0 != memcmp (&ve->pid, sender, sizeof (struct GNUNET_PeerIdentity)))
  {
    GNUNET_break_op (0);
    return;
  }

  if (GNUNET_OK !=
      GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN,
                                &pong->purpose, &pong->signature,
                                &ve->public_key))
  {
    GNUNET_break_op (0);
    return;
  }

  if (GNUNET_TIME_absolute_get_remaining
      (GNUNET_TIME_absolute_ntoh (pong->expiration)).rel_value == 0)
  {
    GNUNET_STATISTICS_update (GST_stats,
                              gettext_noop
                              ("# PONGs dropped, signature expired"), 1,
                              GNUNET_NO);
    return;
  }
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Address validated for peer `%s' with plugin `%s': `%s'\n",

              GNUNET_i2s (sender), tname, GST_plugins_a2s (ve->address));
  /* validity achieved, remember it! */
  ve->expecting_pong = GNUNET_NO;
  ve->valid_until = GNUNET_TIME_relative_to_absolute (HELLO_ADDRESS_EXPIRATION);
  ve->latency = GNUNET_TIME_absolute_get_duration (ve->send_time);
  {
    struct GNUNET_ATS_Information ats;

    ats.type = htonl (GNUNET_ATS_QUALITY_NET_DELAY);
    ats.value = htonl ((uint32_t) ve->latency.rel_value);
    GNUNET_ATS_address_update (GST_ats, ve->address, NULL, &ats, 1);
  }
  /* build HELLO to store in PEERINFO */
  ve->copied = GNUNET_NO;
  hello = GNUNET_HELLO_create (&ve->public_key, &add_valid_peer_address, ve);
  GNUNET_PEERINFO_add_peer (GST_peerinfo, hello, NULL, NULL);
  GNUNET_free (hello);
}
示例#6
0
static int
testDirectory (unsigned int i)
{
  struct GNUNET_FS_DirectoryBuilder *db;
  char *data;
  size_t dlen;
  struct GNUNET_FS_Uri **uris;
  struct GNUNET_CONTAINER_MetaData **mds;
  struct GNUNET_CONTAINER_MetaData *meta;
  struct PCLS cls;
  char *emsg;
  int p;
  int q;
  char uri[512];
  char txt[128];
  int ret = 0;
  struct GNUNET_TIME_Absolute start;
  const char *s;

  cls.max = i;
  uris = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri *) * i);
  mds = GNUNET_malloc (sizeof (struct GNUNET_CONTAINER_MetaData *) * i);
  meta = GNUNET_CONTAINER_meta_data_create ();
  GNUNET_CONTAINER_meta_data_insert (meta, "<test>", EXTRACTOR_METATYPE_TITLE,
                                     EXTRACTOR_METAFORMAT_UTF8, "text/plain",
                                     "A title", strlen ("A title") + 1);
  GNUNET_CONTAINER_meta_data_insert (meta, "<test>",
                                     EXTRACTOR_METATYPE_AUTHOR_NAME,
                                     EXTRACTOR_METAFORMAT_UTF8, "text/plain",
                                     "An author", strlen ("An author") + 1);
  for (p = 0; p < i; p++)
  {
    mds[p] = GNUNET_CONTAINER_meta_data_create ();
    for (q = 0; q <= p; q++)
    {
      GNUNET_snprintf (txt, sizeof (txt), "%u -- %u\n", p, q);
      GNUNET_CONTAINER_meta_data_insert (mds[p], "<test>",
#if HAVE_EXTRACTOR_H && HAVE_LIBEXTRACTOR
                                         q % EXTRACTOR_metatype_get_max (),
#else
                                         q % 128,
#endif
                                         EXTRACTOR_METAFORMAT_UTF8,
                                         "text/plain", txt, strlen (txt) + 1);
    }
    GNUNET_snprintf (uri, sizeof (uri),
                     "gnunet://fs/chk/C282GG70GKK41O4551011DO413KFBVTVMQG1OG30I0K4045N0G41HAPB82G680A02JRVVFO8URVRU2F159011DO41000000022RG820.RNVVVVOOLCLK065B5D04HTNVNSIB2AI022RG8200HSLK1CO1000ATQ98824DMA2032LIMG50CG0K057NVUVG200000H000004400000.%u",
                     p);
    emsg = NULL;
    uris[p] = GNUNET_FS_uri_parse (uri, &emsg);
    if (uris[p] == NULL)
    {
      GNUNET_CONTAINER_meta_data_destroy (mds[p]);
      while (--p > 0)
      {
        GNUNET_CONTAINER_meta_data_destroy (mds[p]);
        GNUNET_FS_uri_destroy (uris[p]);
      }
      GNUNET_free (mds);
      GNUNET_free (uris);
      GNUNET_free (emsg);
      GNUNET_CONTAINER_meta_data_destroy (meta);
      ABORT ();                 /* error in testcase */
    }
    GNUNET_assert (emsg == NULL);
  }
  start = GNUNET_TIME_absolute_get ();
  db = GNUNET_FS_directory_builder_create (meta);
  for (p = 0; p < i; p++)
    GNUNET_FS_directory_builder_add (db, uris[p], mds[p], NULL);
  GNUNET_FS_directory_builder_finish (db, &dlen, (void **) &data);
  s = GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration
                                              (start),
					      GNUNET_YES);
  FPRINTF (stdout,
           "Creating directory with %u entires and total size %llu took %s\n",
           i, (unsigned long long) dlen, s);
  if (i < 100)
  {
    cls.pos = 0;
    cls.uri = uris;
    cls.md = mds;
    GNUNET_FS_directory_list_contents (dlen, data, 0, &processor, &cls);
    GNUNET_assert (cls.pos == i);
  }
  GNUNET_free (data);
  GNUNET_CONTAINER_meta_data_destroy (meta);
  for (p = 0; p < i; p++)
  {
    GNUNET_CONTAINER_meta_data_destroy (mds[p]);
    GNUNET_FS_uri_destroy (uris[p]);
  }
  GNUNET_free (uris);
  GNUNET_free (mds);
  return ret;
}