Example #1
0
/**
 * Main state machine.  Executes the next step of the benchmark
 * depending on the current state.
 *
 * @param cls the `struct CpsRunContext`
 */
static void
run_continuation (void *cls)
{
  struct CpsRunContext *crc = cls;
  size_t size;
  static struct GNUNET_HashCode key;
  static char data[65536];
  char gstr[128];

  ok = (int) crc->phase;
  switch (crc->phase)
  {
  case RP_PUT:
    memset (&key,
            256 - crc->i,
            sizeof (struct GNUNET_HashCode));
    /* most content is 32k */
    size = 32 * 1024;
    if (0 ==
        GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
                                  16)) /* but some of it is less! */
      size = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
                                       32 * 1024);
    crc->size = size = size - (size & 7);       /* always multiple of 8 */
    GNUNET_CRYPTO_hash (&key,
                        sizeof (struct GNUNET_HashCode),
                        &key);
    memset (data,
            (int) crc->j,
            size);
    if (crc->j > 255)
      memset (data,
              (int) (crc->j - 255),
              size / 2);
    data[0] = crc->i;
    GNUNET_assert (NULL !=
                   GNUNET_DATASTORE_put (datastore,
                                         0,
                                         &key,
                                         size,
                                         data,
                                         crc->j + 1,
                                         GNUNET_CRYPTO_random_u32
                                         (GNUNET_CRYPTO_QUALITY_WEAK, 100),
                                         crc->j,
                                         0,
                                         GNUNET_TIME_relative_to_absolute
                                         (GNUNET_TIME_relative_multiply
                                          (GNUNET_TIME_UNIT_SECONDS,
                                           GNUNET_CRYPTO_random_u32
                                           (GNUNET_CRYPTO_QUALITY_WEAK, 1000))),
                                         1,
                                         1,
                                         &check_success, crc));
    break;
  case RP_CUT:
    /* trim down below MAX_SIZE again */
    GNUNET_assert (NULL !=
                   GNUNET_DATASTORE_get_for_replication (datastore,
                                                         1, 1,
                                                         &delete_value,
                                                         crc));
    break;
  case RP_REPORT:
    printf (
#if REPORT_ID
             "\n"
#endif
             "Stored %llu kB / %lluk ops / %llu ops/s\n",
             stored_bytes / 1024,  /* used size in k */
             stored_ops / 1024, /* total operations (in k) */
             1000LL * 1000LL * stored_ops / (1 +
					     GNUNET_TIME_absolute_get_duration
					     (start_time).rel_value_us));
    crc->phase = RP_PUT;
    crc->j = 0;
    GNUNET_SCHEDULER_add_now (&run_continuation,
                              crc);
    break;
  case RP_PUT_QUOTA:
    memset (&key,
            256 - crc->i,
            sizeof (struct GNUNET_HashCode));
    /* most content is 32k */
    size = 32 * 1024;
    if (0 ==
        GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
                                  16)) /* but some of it is less! */
      size = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
                                       32 * 1024);
    crc->size = size = size - (size & 7);       /* always multiple of 8 */
    GNUNET_CRYPTO_hash (&key,
                        sizeof (struct GNUNET_HashCode),
                        &key);
    memset (data,
            (int) crc->j,
            size);
    if (crc->j > 255)
      memset (data,
              (int) (crc->j - 255),
              size / 2);
    data[0] = crc->i;
    GNUNET_assert (NULL !=
                   GNUNET_DATASTORE_put (datastore,
                                         0, /* reservation ID */
                                         &key,
                                         size,
                                         data,
                                         crc->j + 1, /* type */
                                         GNUNET_CRYPTO_random_u32
                                         (GNUNET_CRYPTO_QUALITY_WEAK,
                                          100), /* priority */
                                         crc->j, /* anonymity */
                                         0, /* replication */
                                         GNUNET_TIME_relative_to_absolute
                                         (GNUNET_TIME_relative_multiply
                                          (GNUNET_TIME_UNIT_SECONDS,
                                           GNUNET_CRYPTO_random_u32
                                           (GNUNET_CRYPTO_QUALITY_WEAK, 1000))),
                                         1,
                                         1,
                                         &check_success, crc));
    break;

  case RP_DONE:
    GNUNET_snprintf (gstr,
                     sizeof (gstr),
                     "DATASTORE-%s",
                     plugin_name);
    if ((crc->i == ITERATIONS) && (stored_ops > 0))
    {
      GAUGER (gstr,
              "PUT operation duration",
              GNUNET_TIME_absolute_get_duration (start_time).rel_value_us / 1000LL /
              stored_ops,
              "ms/operation");
      fprintf (stdout,
               "\nPUT performance: %s for %llu operations\n",
               GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start_time),
                                                       GNUNET_YES),
               stored_ops);
      fprintf (stdout,
               "PUT performance: %llu ms/operation\n",
               GNUNET_TIME_absolute_get_duration (start_time).rel_value_us / 1000LL /
               stored_ops);
    }
    GNUNET_DATASTORE_disconnect (datastore,
                                 GNUNET_YES);
    GNUNET_free (crc);
    ok = 0;
    break;
  case RP_ERROR:
    GNUNET_DATASTORE_disconnect (datastore, GNUNET_YES);
    GNUNET_free (crc);
    ok = 1;
    break;
  default:
    GNUNET_assert (0);
  }
}
Example #2
0
/**
 * Evaluate RSA performance.
 *
 * @param len keylength to evaluate with
 */
static void
eval (unsigned int len)
{
  struct GNUNET_TIME_Absolute start;
  struct GNUNET_CRYPTO_RsaSignature *sig;
  struct GNUNET_CRYPTO_RsaSignature *rsig;
  struct GNUNET_CRYPTO_RsaPublicKey *public_key;
  struct GNUNET_CRYPTO_RsaPrivateKey *private_key;
  struct GNUNET_CRYPTO_RsaBlindingKeySecret bsec[10];
  unsigned int i;
  char sbuf[128];
  char *bbuf;
  size_t bbuf_len;
  struct GNUNET_HashCode hc;

  start = GNUNET_TIME_absolute_get ();
  for (i=0;i<10;i++)
  {
    private_key = GNUNET_CRYPTO_rsa_private_key_create (len);
    GNUNET_CRYPTO_rsa_private_key_free (private_key);
  }
  printf ("10x %u-key generation took %s\n",
          len,
          GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start),
                                                  GNUNET_YES));
  GNUNET_snprintf (sbuf,
                   sizeof (sbuf),
                   "RSA %u-key generation",
                   len);
  GAUGER ("UTIL", sbuf,
          64 * 1024 / (1 +
                       GNUNET_TIME_absolute_get_duration
                       (start).rel_value_us / 1000LL), "keys/ms");
  private_key = GNUNET_CRYPTO_rsa_private_key_create (len);
  public_key = GNUNET_CRYPTO_rsa_private_key_get_public (private_key);
  for (i=0;i<10;i++)
    GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
			        &bsec[i], sizeof (bsec[0]));
  /*
  start = GNUNET_TIME_absolute_get ();
  for (i=0;i<10;i++)
    rsa_blinding_key_derive(public_key, &bsec[i]);
  printf ("10x %u-blinding key generation took %s\n",
          len,
          GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start),
                                                  GNUNET_YES));
  GNUNET_snprintf (sbuf,
                   sizeof (sbuf),
                   "RSA %u-blinding key generation",
                   len);
  GAUGER ("UTIL", sbuf,
          64 * 1024 / (1 +
                       GNUNET_TIME_absolute_get_duration
                       (start).rel_value_us / 1000LL), "keys/ms");
  */
  start = GNUNET_TIME_absolute_get ();
  GNUNET_CRYPTO_hash ("test", 4, &hc);
  for (i=0;i<10;i++)
  {
    GNUNET_CRYPTO_rsa_blind (&hc,
                             &bsec[i],
                             public_key,
                             &bbuf, &bbuf_len);
    GNUNET_free (bbuf);
  }
  printf ("10x %u-blinding took %s\n",
          len,
          GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start),
						  GNUNET_YES));
  GNUNET_snprintf (sbuf,
                   sizeof (sbuf),
                   "RSA %u-blinding",
                   len);
  GAUGER ("UTIL",
          sbuf,
          64 * 1024 / (1 +
		       GNUNET_TIME_absolute_get_duration
		       (start).rel_value_us / 1000LL), "ops/ms");
  GNUNET_CRYPTO_rsa_blind (&hc,
                           &bsec[0],
                           public_key,
                           &bbuf, &bbuf_len);
  start = GNUNET_TIME_absolute_get ();
  for (i=0;i<10;i++)
  {
    sig = GNUNET_CRYPTO_rsa_sign_blinded (private_key,
                                          bbuf, bbuf_len);
    GNUNET_CRYPTO_rsa_signature_free (sig);
  }
  printf ("10x %u-signing took %s\n",
          len,
          GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start),
						  GNUNET_YES));
  GNUNET_snprintf (sbuf,
                   sizeof (sbuf),
                   "RSA %u-signing",
                   len);
  GAUGER ("UTIL",
          sbuf,
          64 * 1024 / (1 +
		       GNUNET_TIME_absolute_get_duration
		       (start).rel_value_us / 1000LL), "ops/ms");
  sig = GNUNET_CRYPTO_rsa_sign_blinded (private_key,
                                        bbuf,
                                        bbuf_len);
  start = GNUNET_TIME_absolute_get ();
  for (i=0;i<10;i++)
  {
    rsig = GNUNET_CRYPTO_rsa_unblind (sig,
                                      &bsec[0],
                                      public_key);
    GNUNET_CRYPTO_rsa_signature_free (rsig);
  }
  printf ("10x %u-unblinding took %s\n",
          len,
          GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start),
						  GNUNET_YES));
  GNUNET_snprintf (sbuf,
                   sizeof (sbuf),
                   "RSA %u-unblinding",
                   len);
  GAUGER ("UTIL",
          sbuf,
          64 * 1024 / (1 +
		       GNUNET_TIME_absolute_get_duration
		       (start).rel_value_us / 1000LL), "ops/ms");
  rsig = GNUNET_CRYPTO_rsa_unblind (sig,
                                    &bsec[0],
                                    public_key);
  start = GNUNET_TIME_absolute_get ();
  for (i=0;i<10;i++)
  {
    GNUNET_assert (GNUNET_OK ==
                   GNUNET_CRYPTO_rsa_verify (&hc,
                                             rsig,
                                             public_key));
  }
  printf ("10x %u-verifying took %s\n",
          len,
          GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start),
						  GNUNET_YES));
  GNUNET_snprintf (sbuf,
                   sizeof (sbuf),
                   "RSA %u-verification",
                   len);
  GAUGER ("UTIL",
          sbuf,
          64 * 1024 / (1 +
		       GNUNET_TIME_absolute_get_duration
		       (start).rel_value_us / 1000LL), "ops/ms");
  GNUNET_CRYPTO_rsa_signature_free (sig);
  GNUNET_CRYPTO_rsa_public_key_free (public_key);
  GNUNET_CRYPTO_rsa_private_key_free (private_key);
  GNUNET_free (bbuf);
}
Example #3
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
                                         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;
}
Example #4
0
/**
 * Called by FS client to give information about the progress of an
 * operation.
 *
 * @param cls closure
 * @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`
 */
static void *
progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info)
{
  char *s;
  const char *s2;
  char *t;

  switch (info->status)
  {
  case GNUNET_FS_STATUS_DOWNLOAD_START:
    if (verbose > 1)
      FPRINTF (stderr, _("Starting download `%s'.\n"),
               info->value.download.filename);
    break;
  case GNUNET_FS_STATUS_DOWNLOAD_PROGRESS:
    if (verbose)
    {
      s = GNUNET_strdup (GNUNET_STRINGS_relative_time_to_string (info->value.download.eta,
								 GNUNET_YES));
      if (info->value.download.specifics.progress.block_download_duration.rel_value_us
          == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
        s2 = _("<unknown time>");
      else
        s2 = GNUNET_STRINGS_relative_time_to_string (
						     info->value.download.specifics.progress.block_download_duration,
						     GNUNET_YES);
      t = GNUNET_STRINGS_byte_size_fancy (info->value.download.completed *
                                          1000LL /
                                          (info->value.download.
                                           duration.rel_value_us + 1));
      FPRINTF (stdout,
               _("Downloading `%s' at %llu/%llu (%s remaining, %s/s). Block took %s to download\n"),
               info->value.download.filename,
               (unsigned long long) info->value.download.completed,
               (unsigned long long) info->value.download.size, s, t, s2);
      GNUNET_free (s);
      GNUNET_free (t);
    }
    else
    {
      display_bar (info->value.download.completed,
		   info->value.download.size,
		   60);
    }
    break;
  case GNUNET_FS_STATUS_DOWNLOAD_ERROR:
#if !WINDOWS
    if (0 != isatty (1))
      fprintf (stdout, "\n");
#else
    if (FILE_TYPE_CHAR == GetFileType (GetStdHandle (STD_OUTPUT_HANDLE)))
      fprintf (stdout, "\n");
#endif
    FPRINTF (stderr, _("Error downloading: %s.\n"),
             info->value.download.specifics.error.message);
    GNUNET_SCHEDULER_shutdown ();
    break;
  case GNUNET_FS_STATUS_DOWNLOAD_COMPLETED:
    s = GNUNET_STRINGS_byte_size_fancy (info->value.download.completed * 1000 /
                                        (info->value.download.
                                         duration.rel_value_us + 1));
#if !WINDOWS
    if (0 != isatty (1))
      fprintf (stdout, "\n");
#else
    if (FILE_TYPE_CHAR == GetFileType (GetStdHandle (STD_OUTPUT_HANDLE)))
      fprintf (stdout, "\n");
#endif
    FPRINTF (stdout, _("Downloading `%s' done (%s/s).\n"),
             info->value.download.filename, s);
    GNUNET_free (s);
    if (info->value.download.dc == dc)
      GNUNET_SCHEDULER_shutdown ();
    break;
  case GNUNET_FS_STATUS_DOWNLOAD_STOPPED:
    if (info->value.download.dc == dc)
      GNUNET_SCHEDULER_add_now (&cleanup_task, NULL);
    break;
  case GNUNET_FS_STATUS_DOWNLOAD_ACTIVE:
  case GNUNET_FS_STATUS_DOWNLOAD_INACTIVE:
    break;
  default:
    FPRINTF (stderr, _("Unexpected status: %d\n"), info->status);
    break;
  }
  return NULL;
}
Example #5
0
static void
run (void *cls, char *const *args, const char *cfgfile,
     const struct GNUNET_CONFIGURATION_Handle *cfg)
{
  struct GNUNET_DATACACHE_Handle *h;
  struct GNUNET_HashCode k;
  struct GNUNET_HashCode n;
  struct GNUNET_TIME_Absolute exp;
  struct GNUNET_TIME_Absolute start;
  unsigned int i;
  char gstr[128];

  ok = 0;
  h = GNUNET_DATACACHE_create (cfg, "perfcache");

  if (h == NULL)
  {
    FPRINTF (stderr, "%s", "Failed to initialize datacache.  Database likely not setup, skipping test.\n");
    ok = 77; /* mark test as skipped */
    return;
  }
  exp = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_HOURS);
  start = GNUNET_TIME_absolute_get ();
  memset (&k, 0, sizeof (struct GNUNET_HashCode));
  for (i = 0; i < ITERATIONS; i++)
  {
    if (0 == i % (ITERATIONS / 80))
      FPRINTF (stderr, "%s",  ".");
    GNUNET_CRYPTO_hash (&k, sizeof (struct GNUNET_HashCode), &n);
    ASSERT (GNUNET_OK ==
            GNUNET_DATACACHE_put (h, &k, sizeof (struct GNUNET_HashCode),
                                  (const char *) &n, 1 + i % 16, exp,
				  0, NULL));
    k = n;
  }
  FPRINTF (stderr, "%s",  "\n");
  FPRINTF (stdout, "Stored %u items in %s\n", ITERATIONS,
	   GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start), GNUNET_YES));
  GNUNET_snprintf (gstr, sizeof (gstr), "DATACACHE-%s", plugin_name);
  GAUGER (gstr, "Time to PUT item in datacache",
          GNUNET_TIME_absolute_get_duration (start).rel_value_us / 1000LL / ITERATIONS,
          "ms/item");
  start = GNUNET_TIME_absolute_get ();
  memset (&k, 0, sizeof (struct GNUNET_HashCode));
  for (i = 0; i < ITERATIONS; i++)
  {
    if (0 == i % (ITERATIONS / 80))
      FPRINTF (stderr, "%s",  ".");
    GNUNET_CRYPTO_hash (&k, sizeof (struct GNUNET_HashCode), &n);
    GNUNET_DATACACHE_get (h, &k, 1 + i % 16, &checkIt, &n);
    k = n;
  }
  FPRINTF (stderr, "%s",  "\n");
  FPRINTF (stdout,
           "Found %u/%u items in %s (%u were deleted during storage processing)\n",
           found, ITERATIONS,
           GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start), GNUNET_YES),
           ITERATIONS - found);
  if (found > 0)
    GAUGER (gstr, "Time to GET item from datacache",
            GNUNET_TIME_absolute_get_duration (start).rel_value_us / 1000LL / found,
            "ms/item");
  GNUNET_DATACACHE_destroy (h);
  ASSERT (ok == 0);
  return;
FAILURE:
  if (h != NULL)
    GNUNET_DATACACHE_destroy (h);
  ok = GNUNET_SYSERR;
}
/**
 * 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;
}
Example #7
0
/**
 * Recalculate when we might need to call the excess callback.
 */
static void
update_excess (struct GNUNET_BANDWIDTH_Tracker *av)
{
  struct GNUNET_TIME_Relative delay;
  struct GNUNET_TIME_Absolute now;
  uint64_t delta_time;
  uint64_t delta_avail;
  int64_t left_bytes;
  uint64_t max_carry;
  int64_t current_consumption;

  if (NULL == av->excess_cb)
    return; /* nothing to do */
  now = GNUNET_TIME_absolute_get ();
  delta_time = now.abs_value_us - av->last_update__.abs_value_us;
  delta_avail =
      (delta_time * ((unsigned long long) av->available_bytes_per_s__) +
       500000LL) / 1000000LL;
  current_consumption = av->consumption_since_last_update__ - delta_avail;
  if (current_consumption > av->consumption_since_last_update__)
  {
    /* integer underflow, cap! */
    current_consumption = INT64_MIN;
  }
  /* negative current_consumption means that we have savings */
  max_carry = ((uint64_t) av->available_bytes_per_s__) * av->max_carry_s__;
  if (max_carry < GNUNET_SERVER_MAX_MESSAGE_SIZE)
    max_carry = GNUNET_SERVER_MAX_MESSAGE_SIZE;
  if (max_carry > INT64_MAX)
    max_carry = INT64_MAX;
  left_bytes = current_consumption + max_carry;
  if (left_bytes < current_consumption)
  {
    /* integer overflow, cap! */
    left_bytes = INT64_MAX;
  }
  /* left_bytes now contains the number of bytes needed until
     we have more savings than allowed */
  if (left_bytes < 0)
  {
    /* having excess already */
    delay = GNUNET_TIME_UNIT_ZERO;
  }
  else
  {
    double factor = 1.0 * left_bytes / (double) av->available_bytes_per_s__; 
    delay = GNUNET_TIME_relative_saturating_multiply (GNUNET_TIME_UNIT_SECONDS,
                                                      (unsigned long long) factor);
  }
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
	      "At %llu bps it will take us %s for %lld bytes to reach excess threshold\n",
	      (unsigned long long) av->available_bytes_per_s__,
	      GNUNET_STRINGS_relative_time_to_string (delay,
						      GNUNET_NO),
	      (long long) left_bytes);
  if (NULL != av->excess_task)
    GNUNET_SCHEDULER_cancel (av->excess_task);
  av->excess_task = GNUNET_SCHEDULER_add_delayed (delay,
                                                  &excess_trigger,
                                                  av);
}
Example #8
0
/**
 * Figure out when and how to transmit to the given peer.
 *
 * @param cls the `struct PeerPlan`
 */
static void
schedule_peer_transmission (void *cls)
{
  struct PeerPlan *pp = cls;
  struct GSF_RequestPlan *rp;
  struct GNUNET_TIME_Relative delay;

  if (NULL != pp->task)
  {
    pp->task = NULL;
  }
  else
  {
    GNUNET_assert (NULL != pp->env);
    pp->env = NULL;
  }
  /* move ready requests to priority queue */
  while ((NULL != (rp = GNUNET_CONTAINER_heap_peek (pp->delay_heap))) &&
         (0 == GNUNET_TIME_absolute_get_remaining
          (rp->earliest_transmission).rel_value_us))
  {
    GNUNET_assert (rp == GNUNET_CONTAINER_heap_remove_root (pp->delay_heap));
    rp->hn = GNUNET_CONTAINER_heap_insert (pp->priority_heap,
                                           rp,
                                           rp->priority);
  }
  if (0 == GNUNET_CONTAINER_heap_get_size (pp->priority_heap))
  {
    /* priority heap (still) empty, check for delay... */
    rp = GNUNET_CONTAINER_heap_peek (pp->delay_heap);
    if (NULL == rp)
    {
      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                  "No active requests for plan %p.\n",
                  pp);
      return;                   /* both queues empty */
    }
    delay = GNUNET_TIME_absolute_get_remaining (rp->earliest_transmission);
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "Sleeping for %s before retrying requests on plan %p.\n",
                GNUNET_STRINGS_relative_time_to_string (delay,
							GNUNET_YES),
		pp);
    GNUNET_STATISTICS_set (GSF_stats,
                           gettext_noop ("# delay heap timeout (ms)"),
                           delay.rel_value_us / 1000LL, GNUNET_NO);

    pp->task
      = GNUNET_SCHEDULER_add_at (rp->earliest_transmission,
                                 &schedule_peer_transmission,
                                 pp);
    return;
  }
#if INSANE_STATISTICS
  GNUNET_STATISTICS_update (GSF_stats,
			    gettext_noop ("# query plans executed"),
                            1,
			    GNUNET_NO);
#endif
  /* process from priority heap */
  rp = GNUNET_CONTAINER_heap_remove_root (pp->priority_heap);
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Executing query plan %p\n",
              rp);
  GNUNET_assert (NULL != rp);
  rp->hn = NULL;
  rp->last_transmission = GNUNET_TIME_absolute_get ();
  rp->transmission_counter++;
  total_delay++;
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Executing plan %p executed %u times, planning retransmission\n",
              rp,
	      rp->transmission_counter);
  GNUNET_assert (NULL == pp->env);
  pp->env = GSF_pending_request_get_message_ (get_latest (rp));
  GNUNET_MQ_notify_sent (pp->env,
			 &schedule_peer_transmission,
			 pp);
  GSF_peer_transmit_ (pp->cp,
		      GNUNET_YES,
		      rp->priority,
		      pp->env);
  GNUNET_STATISTICS_update (GSF_stats,
                            gettext_noop ("# query messages sent to other peers"),
                            1,
                            GNUNET_NO);
  plan (pp,
	rp);
}
Example #9
0
/**
 * Insert the given request plan into the heap with the appropriate weight.
 *
 * @param pp associated peer's plan
 * @param rp request to plan
 */
static void
plan (struct PeerPlan *pp,
      struct GSF_RequestPlan *rp)
{
#define N ((double)128.0)
  /**
   * Running average delay we currently impose.
   */
  static double avg_delay;

  struct GSF_PendingRequestData *prd;
  struct GNUNET_TIME_Relative delay;

  GNUNET_assert (rp->pp == pp);
  GNUNET_STATISTICS_set (GSF_stats,
                         gettext_noop ("# average retransmission delay (ms)"),
                         total_delay * 1000LL / plan_count, GNUNET_NO);
  prd = GSF_pending_request_get_data_ (rp->pe_head->pr);

  if (rp->transmission_counter < 8)
    delay =
        GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
                                       rp->transmission_counter);
  else if (rp->transmission_counter < 32)
    delay =
        GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
                                       8 +
                                       (1LL << (rp->transmission_counter - 8)));
  else
    delay =
        GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
                                       8 + (1LL << 24));
  delay.rel_value_us =
    GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
			      delay.rel_value_us + 1);
  /* Add 0.01 to avg_delay to avoid division-by-zero later */
  avg_delay = (((avg_delay * (N - 1.0)) + delay.rel_value_us) / N) + 0.01;

  /*
   * For the priority, we need to consider a few basic rules:
   * 1) if we just started requesting (delay is small), we should
   * virtually always have a priority of zero.
   * 2) for requests with average latency, our priority should match
   * the average priority observed on the network
   * 3) even the longest-running requests should not be WAY out of
   * the observed average (thus we bound by a factor of 2)
   * 4) we add +1 to the observed average priority to avoid everyone
   * staying put at zero (2 * 0 = 0...).
   *
   * Using the specific calculation below, we get:
   *
   * delay = 0 => priority = 0;
   * delay = avg delay => priority = running-average-observed-priority;
   * delay >> avg_delay => priority = 2 * running-average-observed-priority;
   *
   * which satisfies all of the rules above.
   *
   * Note: M_PI_4 = PI/4 = arctan(1)
   */
  rp->priority =
      round ((GSF_current_priorities +
              1.0) * atan (delay.rel_value_us / avg_delay)) / M_PI_4;
  /* Note: usage of 'round' and 'atan' requires -lm */

  if (rp->transmission_counter != 0)
    delay.rel_value_us += TTL_DECREMENT * 1000;
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Considering (re)transmission number %u in %s\n",
              (unsigned int) rp->transmission_counter,
              GNUNET_STRINGS_relative_time_to_string (delay,
						      GNUNET_YES));
  rp->earliest_transmission = GNUNET_TIME_relative_to_absolute (delay);
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Earliest (re)transmission for `%s' in %us\n",
              GNUNET_h2s (&prd->query),
	      rp->transmission_counter);
  GNUNET_assert (rp->hn == NULL);
  if (0 == GNUNET_TIME_absolute_get_remaining (rp->earliest_transmission).rel_value_us)
    rp->hn = GNUNET_CONTAINER_heap_insert (pp->priority_heap,
					   rp,
					   rp->priority);
  else
    rp->hn =
        GNUNET_CONTAINER_heap_insert (pp->delay_heap,
				      rp,
                                      rp->earliest_transmission.abs_value_us);
  GNUNET_assert (GNUNET_YES ==
                 GNUNET_CONTAINER_multihashmap_contains_value (pp->plan_map,
                                                               get_rp_key (rp),
                                                               rp));
#undef N
}
Example #10
0
/**
 * Request for a service to be started.
 *
 * @param h handle to ARM
 * @param service_name name of the service
 * @param std_inheritance inheritance of std streams
 * @param timeout how long to wait before failing for good
 * @param cont callback to invoke after request is sent or not sent
 * @param cont_cls closure for callback
 */
void
GNUNET_ARM_request_service_start (struct GNUNET_ARM_Handle *h,
				  const char *service_name,
				  enum GNUNET_OS_InheritStdioFlags std_inheritance,
				  struct GNUNET_TIME_Relative timeout,
				  GNUNET_ARM_ResultCallback cont,
				  void *cont_cls)
{
  struct ARMControlMessage *cm;
  size_t slen;

  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Asked to start service `%s' within %s\n", service_name,
       GNUNET_STRINGS_relative_time_to_string (timeout, GNUNET_NO));
  if (0 == strcasecmp ("arm", service_name))
  {
    /* Possible cases:
     * 1) We're connected to ARM already. Invoke the callback immediately.
     * 2) We're not connected to ARM.
     *    Cancel any reconnection attempts temporarily, then perform
     *    a service test.
     */
    if (GNUNET_NO == h->currently_down)
    {
      LOG (GNUNET_ERROR_TYPE_DEBUG, "ARM is already running\n");
      if (NULL != cont)
        cont (cont_cls, GNUNET_ARM_REQUEST_SENT_OK, "arm", GNUNET_ARM_RESULT_IS_STARTED_ALREADY);
    }
    else if (GNUNET_NO == h->service_test_is_active)
    {
      if (NULL != h->cth)
      {
        GNUNET_CLIENT_notify_transmit_ready_cancel (h->cth);
        h->cth = NULL;
      }
      if (NULL != h->client)
      {
        GNUNET_CLIENT_disconnect (h->client);
        h->client = NULL;
      }
      if (GNUNET_SCHEDULER_NO_TASK != h->reconnect_task)
      {
        GNUNET_SCHEDULER_cancel (h->reconnect_task);
        h->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
      }

      LOG (GNUNET_ERROR_TYPE_DEBUG,
          "Not connected to ARM, will do a service test\n");

      slen = strlen ("arm") + 1;
      cm = GNUNET_malloc (sizeof (struct ARMControlMessage) + slen);
      cm->h = h;
      cm->result_cont = cont;
      cm->cont_cls = cont_cls;
      cm->timeout = GNUNET_TIME_relative_to_absolute (timeout);
      cm->std_inheritance = std_inheritance;
      memcpy (&cm[1], service_name, slen);
      h->service_test_is_active = GNUNET_YES;
      GNUNET_CLIENT_service_test ("arm", h->cfg, timeout, &arm_service_report,
				  cm);
    }
    else
    {
      /* Service test is already running - tell user to chill out and try
       * again later.
       */
      LOG (GNUNET_ERROR_TYPE_DEBUG, "Service test is already in progress, we're busy\n");
      if (NULL != cont)
        cont (cont_cls, GNUNET_ARM_REQUEST_BUSY, NULL, 0);
    }
    return;
  }
  change_service (h, service_name, timeout, cont, cont_cls,
		  GNUNET_MESSAGE_TYPE_ARM_START);
}