Esempio n. 1
0
/**
 * @brief Restore the peers on disk to #valid_peers.
 */
static void
restore_valid_peers ()
{
  off_t file_size;
  uint32_t num_peers;
  struct GNUNET_DISK_FileHandle *fh;
  char *buf;
  ssize_t size_read;
  char *iter_buf;
  char *str_repr;
  const struct GNUNET_PeerIdentity *peer;

  if (0 == strncmp ("DISABLE", filename_valid_peers, 7))
  {
    return;
  }

  if (GNUNET_OK != GNUNET_DISK_file_test (filename_valid_peers))
  {
    return;
  }
  fh = GNUNET_DISK_file_open (filename_valid_peers,
                              GNUNET_DISK_OPEN_READ,
                              GNUNET_DISK_PERM_NONE);
  GNUNET_assert (NULL != fh);
  GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_handle_size (fh, &file_size));
  num_peers = file_size / 53;
  buf = GNUNET_malloc (file_size);
  size_read = GNUNET_DISK_file_read (fh, buf, file_size);
  GNUNET_assert (size_read == file_size);
  LOG (GNUNET_ERROR_TYPE_DEBUG,
      "Restoring %" PRIu32 " peers from file `%s'\n",
      num_peers,
      filename_valid_peers);
  for (iter_buf = buf; iter_buf < buf + file_size - 1; iter_buf += 53)
  {
    str_repr = GNUNET_strndup (iter_buf, 53);
    peer = s2i_full (str_repr);
    GNUNET_free (str_repr);
    add_valid_peer (peer);
    LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Restored valid peer %s from disk\n",
        GNUNET_i2s_full (peer));
  }
  iter_buf = NULL;
  GNUNET_free (buf);
  LOG (GNUNET_ERROR_TYPE_DEBUG,
      "num_peers: %" PRIu32 ", _size (valid_peers): %u\n",
      num_peers,
      GNUNET_CONTAINER_multipeermap_size (valid_peers));
  if (num_peers != GNUNET_CONTAINER_multipeermap_size (valid_peers))
  {
    LOG (GNUNET_ERROR_TYPE_WARNING,
        "Number of restored peers does not match file size. Have probably duplicates.\n");
  }
  GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh));
  LOG (GNUNET_ERROR_TYPE_DEBUG,
      "Restored %u valid peers from disk\n",
      GNUNET_CONTAINER_multipeermap_size (valid_peers));
}
Esempio n. 2
0
/**
 * Shutdown database connection and associate data
 * structures.
 * @param plugin the plugin context (state for this module)
 */
static void
database_shutdown (struct Plugin *plugin)
{
  struct GNUNET_DISK_FileHandle *fh;
  fh = GNUNET_DISK_file_open (plugin->fn,
                              GNUNET_DISK_OPEN_CREATE |
                              GNUNET_DISK_OPEN_TRUNCATE |
                              GNUNET_DISK_OPEN_READWRITE,
                              GNUNET_DISK_PERM_USER_WRITE |
                              GNUNET_DISK_PERM_USER_READ);
  if (NULL == fh)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("Unable to initialize file: %s.\n"),
                plugin->fn);
    return;
  }

  GNUNET_CONTAINER_multihashmap_iterate (plugin->hm,
                                         &store_and_free_entries,
                                         fh);
  GNUNET_CONTAINER_multihashmap_destroy (plugin->hm);
  GNUNET_DISK_file_close (fh);

}
Esempio n. 3
0
/**
 * Get the namespace ID belonging to the given namespace name.
 *
 * @param cfg configuration to use
 * @param ns_uname unique (!) human-readable name for the namespace
 * @param nsid set to namespace ID based on 'ns_uname'
 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
 */
int
GNUNET_PSEUDONYM_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg,
    const char *ns_uname, struct GNUNET_HashCode * nsid)
{
  size_t slen;
  uint64_t len;
  unsigned int idx;
  char *name;
  struct GNUNET_HashCode nh;
  char *fn;
  struct GNUNET_DISK_FileHandle *fh;

  idx = -1;
  slen = strlen (ns_uname);
  while ((slen > 0) && (1 != SSCANF (&ns_uname[slen - 1], "-%u", &idx)))
    slen--;
  if (slen == 0)
    return GNUNET_SYSERR;
  name = GNUNET_strdup (ns_uname);
  name[slen - 1] = '\0';

  GNUNET_CRYPTO_hash (name, strlen (name), &nh);
  GNUNET_free (name);
  fn = get_data_filename (cfg, PS_NAMES_DIR, &nh);
  GNUNET_assert (fn != NULL);

  if ((GNUNET_OK != GNUNET_DISK_file_test (fn) ||
       (GNUNET_OK != GNUNET_DISK_file_size (fn, &len, GNUNET_YES, GNUNET_YES))) ||
      ((idx + 1) * sizeof (struct GNUNET_HashCode) > len))
  {
    GNUNET_free (fn);
    return GNUNET_SYSERR;
  }
  fh = GNUNET_DISK_file_open (fn,
                              GNUNET_DISK_OPEN_CREATE |
                              GNUNET_DISK_OPEN_READWRITE,
                              GNUNET_DISK_PERM_USER_READ |
                              GNUNET_DISK_PERM_USER_WRITE);
  GNUNET_free (fn);
  if (GNUNET_SYSERR ==
      GNUNET_DISK_file_seek (fh, idx * sizeof (struct GNUNET_HashCode),
			     GNUNET_DISK_SEEK_SET))
  {
    GNUNET_DISK_file_close (fh);
    return GNUNET_SYSERR;
  }
  if (sizeof (struct GNUNET_HashCode) !=
      GNUNET_DISK_file_read (fh, nsid, sizeof (struct GNUNET_HashCode)))
  {
    GNUNET_DISK_file_close (fh);
    return GNUNET_SYSERR;
  }
  GNUNET_DISK_file_close (fh);
  return GNUNET_OK;
}
Esempio n. 4
0
/**
 * Return unique variant of the namespace name.
 * Use it after GNUNET_PSEUDONYM_get_info() to make sure
 * that name is unique.
 *
 * @param cfg configuration
 * @param nsid cryptographic ID of the namespace
 * @param name name to uniquify
 * @param suffix if not NULL, filled with the suffix value
 * @return NULL on failure (should never happen), name on success.
 *         Free the name with GNUNET_free().
 */
char *
GNUNET_PSEUDONYM_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg,
    const struct GNUNET_HashCode * nsid, const char *name, unsigned int *suffix)
{
  struct GNUNET_HashCode nh;
  uint64_t len;
  char *fn;
  struct GNUNET_DISK_FileHandle *fh;
  unsigned int i;
  unsigned int idx;
  char *ret;
  struct stat sbuf;

  GNUNET_CRYPTO_hash (name, strlen (name), &nh);
  fn = get_data_filename (cfg, PS_NAMES_DIR, &nh);
  GNUNET_assert (fn != NULL);

  len = 0;
  if (0 == STAT (fn, &sbuf))
    GNUNET_break (GNUNET_OK == GNUNET_DISK_file_size (fn, &len, GNUNET_YES, GNUNET_YES));
  fh = GNUNET_DISK_file_open (fn,
                              GNUNET_DISK_OPEN_CREATE |
                              GNUNET_DISK_OPEN_READWRITE,
                              GNUNET_DISK_PERM_USER_READ |
                              GNUNET_DISK_PERM_USER_WRITE);
  i = 0;
  idx = -1;
  while ((len >= sizeof (struct GNUNET_HashCode)) &&
         (sizeof (struct GNUNET_HashCode) ==
          GNUNET_DISK_file_read (fh, &nh, sizeof (struct GNUNET_HashCode))))
  {
    if (0 == memcmp (&nh, nsid, sizeof (struct GNUNET_HashCode)))
    {
      idx = i;
      break;
    }
    i++;
    len -= sizeof (struct GNUNET_HashCode);
  }
  if (idx == -1)
  {
    idx = i;
    if (sizeof (struct GNUNET_HashCode) !=
        GNUNET_DISK_file_write (fh, nsid, sizeof (struct GNUNET_HashCode)))
      LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "write", fn);
  }
  GNUNET_DISK_file_close (fh);
  ret = GNUNET_malloc (strlen (name) + 32);
  GNUNET_snprintf (ret, strlen (name) + 32, "%s-%u", name, idx);
  if (suffix != NULL)
    *suffix = idx;
  GNUNET_free (fn);
  return ret;
}
Esempio n. 5
0
static void
write_bw_gnuplot_script (char * fn, struct LoggingPeer *lp, char **fs, int slaves)
{
  struct GNUNET_DISK_FileHandle *f;
  char * gfn;
  char *data;
  int c_s;

  GNUNET_asprintf (&gfn, "gnuplot_bw_%s",fn);
  fprintf (stderr, "Writing bandwidth plot for master %u to `%s'\n",
      lp->peer->no, gfn);

  f = GNUNET_DISK_file_open (gfn,
      GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE,
      GNUNET_DISK_PERM_USER_EXEC | GNUNET_DISK_PERM_USER_READ |
      GNUNET_DISK_PERM_USER_WRITE);
  if (NULL == f)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot open gnuplot file `%s'\n", gfn);
    GNUNET_free (gfn);
    return;
  }

  /* Write header */
  if (GNUNET_SYSERR == GNUNET_DISK_file_write(f, BW_TEMPLATE, strlen(BW_TEMPLATE)))
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
        "Cannot write data to plot file `%s'\n", gfn);

  for (c_s = 0; c_s < slaves; c_s++)
  {
    GNUNET_asprintf (&data, "%s"\
        "'%s' using 2:%u with lines title 'BW out master %u - Slave %u ', \\\n" \
        "'%s' using 2:%u with lines title 'BW in master %u - Slave %u '"\
        "%s\n",
        (0 == c_s) ? "plot " :"",
        fs[c_s],
        LOG_ITEMS_TIME + LOG_ITEM_ATS_BW_OUT,
        lp->peer->no, c_s,
        fs[c_s],
        LOG_ITEMS_TIME + LOG_ITEM_ATS_BW_IN,
        lp->peer->no, c_s,
        (c_s < lp->peer->num_partners -1) ? ", \\" : "\n pause -1");
    if (GNUNET_SYSERR == GNUNET_DISK_file_write(f, data, strlen(data)))
        GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot write data to plot file `%s'\n", gfn);
    GNUNET_free (data);
  }

  if (GNUNET_SYSERR == GNUNET_DISK_file_close(f))
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot close gnuplot file `%s'\n", gfn);
  else
    GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Data successfully written to plot file `%s'\n", gfn);
  GNUNET_free (gfn);
}
Esempio n. 6
0
/**
 * @brief Store the peers currently in #valid_peers to disk.
 */
static void
store_valid_peers ()
{
  struct GNUNET_DISK_FileHandle *fh;
  uint32_t number_written_peers;
  int ret;

  if (0 == strncmp ("DISABLE", filename_valid_peers, 7))
  {
    return;
  }

  ret = GNUNET_DISK_directory_create_for_file (filename_valid_peers);
  if (GNUNET_SYSERR == ret)
  {
    LOG (GNUNET_ERROR_TYPE_WARNING,
        "Not able to create directory for file `%s'\n",
        filename_valid_peers);
    GNUNET_break (0);
  }
  else if (GNUNET_NO == ret)
  {
    LOG (GNUNET_ERROR_TYPE_WARNING,
        "Directory for file `%s' exists but is not writable for us\n",
        filename_valid_peers);
    GNUNET_break (0);
  }
  fh = GNUNET_DISK_file_open (filename_valid_peers,
                              GNUNET_DISK_OPEN_WRITE |
                                  GNUNET_DISK_OPEN_CREATE,
                              GNUNET_DISK_PERM_USER_READ |
                                  GNUNET_DISK_PERM_USER_WRITE);
  if (NULL == fh)
  {
    LOG (GNUNET_ERROR_TYPE_WARNING,
        "Not able to write valid peers to file `%s'\n",
        filename_valid_peers);
    return;
  }
  LOG (GNUNET_ERROR_TYPE_DEBUG,
      "Writing %u valid peers to disk\n",
      GNUNET_CONTAINER_multipeermap_size (valid_peers));
  number_written_peers =
    GNUNET_CONTAINER_multipeermap_iterate (valid_peers,
                                           store_peer_presistently_iterator,
                                           fh);
  GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh));
  GNUNET_assert (number_written_peers ==
      GNUNET_CONTAINER_multipeermap_size (valid_peers));
}
/**
 * Function to load keys
 */
static int
load_keys (const struct GNUNET_CONFIGURATION_Handle *c)
{
    char *data_dir;
    char *idfile;
    uint64_t fsize;

    data_dir = NULL;
    idfile = NULL;
    fsize = 0;
    data_dir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR);
    GNUNET_asprintf (&idfile, "%s/testing_hostkeys.ecc", data_dir);
    GNUNET_free (data_dir);
    data_dir = NULL;
    if (GNUNET_OK !=
            GNUNET_DISK_file_size (idfile, &fsize, GNUNET_YES, GNUNET_YES))
    {
        GNUNET_free (idfile);
        return GNUNET_SYSERR;
    }
    if (0 != (fsize % GNUNET_TESTING_HOSTKEYFILESIZE))
    {
        LOG (GNUNET_ERROR_TYPE_ERROR,
             _("Incorrect hostkey file format: %s\n"), idfile);
        GNUNET_free (idfile);
        return GNUNET_SYSERR;
    }
    hostkeys_fd = GNUNET_DISK_file_open (idfile, GNUNET_DISK_OPEN_READ,
                                         GNUNET_DISK_PERM_NONE);
    if (NULL == hostkeys_fd)
    {
        GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", idfile);
        GNUNET_free (idfile);
        return GNUNET_SYSERR;
    }
    GNUNET_free (idfile);
    idfile = NULL;
    hostkeys_data = GNUNET_DISK_file_map (hostkeys_fd,
                                          &hostkeys_map,
                                          GNUNET_DISK_MAP_TYPE_READ,
                                          fsize);
    if (NULL == hostkeys_data)
    {

        GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "mmap");
        return GNUNET_SYSERR;
    }
    num_hostkeys = fsize / GNUNET_TESTING_HOSTKEYFILESIZE;
    return GNUNET_OK;
}
Esempio n. 8
0
/**
 * Main function that will be run by the scheduler.
 *
 * @param cls closure
 * @param args remaining command-line arguments
 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
 * @param cfg configuration
 */
static void
run (void *cls, char *const *args, const char *cfgfile,
     const struct GNUNET_CONFIGURATION_Handle *cfg)
{
  struct GNUNET_DISK_MapHandle *map;
  struct GNUNET_DISK_FileHandle *h;
  void *data;
  size_t len;
  uint64_t size;
  const char *filename;
  int i;

  if (NULL == args[0])
  {
    FPRINTF (stderr, "%s",  _("You must specify a filename to inspect.\n"));
    ret = 1;
    return;
  }
  i = 0;
  while (NULL != (filename = args[i++]))
  {
    if ((GNUNET_OK != GNUNET_DISK_file_size (filename, &size, GNUNET_YES, GNUNET_YES)) ||
        (NULL ==
         (h =
          GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READ,
                                 GNUNET_DISK_PERM_NONE))))
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to read directory `%s'\n"),
                  filename);
      ret = 1;
      continue;
    }
    len = (size_t) size;
    data = GNUNET_DISK_file_map (h, &map, GNUNET_DISK_MAP_TYPE_READ, len);
    GNUNET_assert (NULL != data);
    if (GNUNET_OK != GNUNET_FS_directory_list_contents (len, data, 0, &print_entry, NULL))
      fprintf (stdout, _("`%s' is not a GNUnet directory\n"),
	       filename);
    else
      printf ("\n");
    GNUNET_DISK_file_unmap (map);
    GNUNET_DISK_file_close (h);
  }
}
Esempio n. 9
0
/**
 * Compute the hash of an entire file.
 *
 * @param priority scheduling priority to use
 * @param filename name of file to hash
 * @param blocksize number of bytes to process in one task
 * @param callback function to call upon completion
 * @param callback_cls closure for callback
 * @return NULL on (immediate) errror
 */
struct GNUNET_CRYPTO_FileHashContext *
GNUNET_CRYPTO_hash_file (enum GNUNET_SCHEDULER_Priority priority,
                         const char *filename, size_t blocksize,
                         GNUNET_CRYPTO_HashCompletedCallback callback,
                         void *callback_cls)
{
    struct GNUNET_CRYPTO_FileHashContext *fhc;

    GNUNET_assert (blocksize > 0);
    fhc =
        GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_FileHashContext) + blocksize);
    fhc->callback = callback;
    fhc->callback_cls = callback_cls;
    fhc->buffer = (unsigned char *) &fhc[1];
    fhc->filename = GNUNET_strdup (filename);
    if (GPG_ERR_NO_ERROR != gcry_md_open (&fhc->md, GCRY_MD_SHA512, 0))
    {
        GNUNET_break (0);
        GNUNET_free (fhc);
        return NULL;
    }
    fhc->bsize = blocksize;
    if (GNUNET_OK != GNUNET_DISK_file_size (filename, &fhc->fsize, GNUNET_NO, GNUNET_YES))
    {
        GNUNET_free (fhc->filename);
        GNUNET_free (fhc);
        return NULL;
    }
    fhc->fh =
        GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READ,
                               GNUNET_DISK_PERM_NONE);
    if (!fhc->fh)
    {
        GNUNET_free (fhc->filename);
        GNUNET_free (fhc);
        return NULL;
    }
    fhc->priority = priority;
    fhc->task =
        GNUNET_SCHEDULER_add_with_priority (priority, &file_hash_task, fhc);
    return fhc;
}
Esempio n. 10
0
static int
testOpenClose ()
{
  struct GNUNET_DISK_FileHandle *fh;
  uint64_t size;

  fh = GNUNET_DISK_file_open (".testfile",
                              GNUNET_DISK_OPEN_READWRITE |
                              GNUNET_DISK_OPEN_CREATE,
                              GNUNET_DISK_PERM_USER_READ |
                              GNUNET_DISK_PERM_USER_WRITE);
  GNUNET_assert (GNUNET_NO == GNUNET_DISK_handle_invalid (fh));
  GNUNET_break (5 == GNUNET_DISK_file_write (fh, "Hello", 5));
  GNUNET_DISK_file_close (fh);
  GNUNET_break (GNUNET_OK ==
                GNUNET_DISK_file_size (".testfile", &size, GNUNET_NO, GNUNET_YES));
  if (size != 5)
    return 1;
  GNUNET_break (0 == UNLINK (".testfile"));

  return 0;
}
Esempio n. 11
0
/**
 * Connect to the datastore and remove the blocks.
 *
 * @param uc context for the unindex operation.
 */
void
GNUNET_FS_unindex_do_remove_ (struct GNUNET_FS_UnindexContext *uc)
{
  if (NULL == uc->dsh)
    uc->dsh = GNUNET_DATASTORE_connect (uc->h->cfg);
  if (NULL == uc->dsh)
  {
    uc->state = UNINDEX_STATE_ERROR;
    uc->emsg = GNUNET_strdup (_("Failed to connect to `datastore' service."));
    GNUNET_FS_unindex_sync_ (uc);
    signal_unindex_error (uc);
    return;
  }
  uc->fh =
      GNUNET_DISK_file_open (uc->filename, GNUNET_DISK_OPEN_READ,
                             GNUNET_DISK_PERM_NONE);
  if (NULL == uc->fh)
  {
    GNUNET_DATASTORE_disconnect (uc->dsh, GNUNET_NO);
    uc->dsh = NULL;
    uc->state = UNINDEX_STATE_ERROR;
    uc->emsg = GNUNET_strdup (_("Failed to open file for unindexing."));
    GNUNET_FS_unindex_sync_ (uc);
    signal_unindex_error (uc);
    return;
  }
  uc->tc =
      GNUNET_FS_tree_encoder_create (uc->h,
                                     uc->file_size,
                                     uc,
                                     &unindex_reader,
                                     &unindex_process,
                                     &unindex_progress,
                                     &unindex_extract_keywords);
  GNUNET_FS_tree_encoder_next (uc->tc);
}
Esempio n. 12
0
static void
write_throughput_gnuplot_script (char * fn, struct LoggingPeer *lp, char **fs, int slaves)
{
  struct GNUNET_DISK_FileHandle *f;
  char * gfn;
  char *data;
  int c_s;

  GNUNET_asprintf (&gfn, "gnuplot_throughput_%s",fn);
  fprintf (stderr, "Writing throughput plot for master %u and %u slaves to `%s'\n",
      lp->peer->no, slaves, gfn);

  f = GNUNET_DISK_file_open (gfn,
      GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE,
      GNUNET_DISK_PERM_USER_EXEC | GNUNET_DISK_PERM_USER_READ |
      GNUNET_DISK_PERM_USER_WRITE);
  if (NULL == f)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot open gnuplot file `%s'\n", gfn);
    GNUNET_free (gfn);
    return;
  }

  /* Write header */
  if (GNUNET_SYSERR == GNUNET_DISK_file_write(f, THROUGHPUT_TEMPLATE,
      strlen(THROUGHPUT_TEMPLATE)))
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
        "Cannot write data to plot file `%s'\n", gfn);

  /* Write master data */
  GNUNET_asprintf (&data,
      "plot '%s' using 2:%u with lines title 'Master %u send total', \\\n" \
      "'%s' using 2:%u with lines title 'Master %u receive total', \\\n",
      fn, LOG_ITEMS_TIME + LOG_ITEM_THROUGHPUT_SENT, lp->peer->no,
      fn, LOG_ITEMS_TIME + LOG_ITEM_THROUGHPUT_RECV, lp->peer->no);
  if (GNUNET_SYSERR == GNUNET_DISK_file_write(f, data, strlen(data)))
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot write data to plot file `%s'\n", gfn);
  GNUNET_free (data);

  for (c_s = 0; c_s < slaves; c_s++)
  {
    GNUNET_asprintf (&data, "'%s' using 2:%u with lines title 'Master %u - Slave %u send', \\\n" \
        "'%s' using 2:%u with lines title 'Master %u - Slave %u receive'%s\n",
        fs[c_s],
        LOG_ITEMS_TIME + LOG_ITEM_THROUGHPUT_SENT,
        lp->peer->no,
        lp->peer->partners[c_s].dest->no,
        fs[c_s],
        LOG_ITEMS_TIME + LOG_ITEM_THROUGHPUT_RECV,
        lp->peer->no,
        lp->peer->partners[c_s].dest->no,
        (c_s < lp->peer->num_partners -1) ? ", \\" : "\n pause -1");
    if (GNUNET_SYSERR == GNUNET_DISK_file_write(f, data, strlen(data)))
        GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot write data to plot file `%s'\n", gfn);
    GNUNET_free (data);
  }

  if (GNUNET_SYSERR == GNUNET_DISK_file_close(f))
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
        "Cannot close gnuplot file `%s'\n", gfn);
  else
    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
        "Data successfully written to plot file `%s'\n", gfn);
  GNUNET_free (gfn);
}
/**
 * We've received an on-demand encoded block from the datastore.
 * Attempt to do on-demand encoding and (if successful), call the
 * continuation with the resulting block.  On error, clean up and ask
 * the datastore for more results.
 *
 * @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
 * @param cont function to call with the actual block (at most once, on success)
 * @param cont_cls closure for cont
 * @return GNUNET_OK on success
 */
int
GNUNET_FS_handle_on_demand_block (const struct GNUNET_HashCode * key, uint32_t size,
                                  const void *data, enum GNUNET_BLOCK_Type type,
                                  uint32_t priority, uint32_t anonymity,
                                  struct GNUNET_TIME_Absolute expiration,
                                  uint64_t uid,
                                  GNUNET_DATASTORE_DatumProcessor cont,
                                  void *cont_cls)
{
  const struct OnDemandBlock *odb;
  struct GNUNET_HashCode nkey;
  struct GNUNET_CRYPTO_AesSessionKey skey;
  struct GNUNET_CRYPTO_AesInitializationVector iv;
  struct GNUNET_HashCode query;
  ssize_t nsize;
  char ndata[DBLOCK_SIZE];
  char edata[DBLOCK_SIZE];
  const char *fn;
  struct GNUNET_DISK_FileHandle *fh;
  uint64_t off;
  struct IndexInfo *ii;

  if (size != sizeof (struct OnDemandBlock))
  {
    GNUNET_break (0);
    GNUNET_DATASTORE_remove (dsh, key, size, data, -1, -1,
                             GNUNET_TIME_UNIT_FOREVER_REL, &remove_cont, NULL);
    return GNUNET_SYSERR;
  }
  odb = (const struct OnDemandBlock *) data;
  off = GNUNET_ntohll (odb->offset);
  ii = GNUNET_CONTAINER_multihashmap_get (ifm, &odb->file_id);
  if (NULL == ii)
  {
    GNUNET_break (0);
    return GNUNET_SYSERR;
  }
  fn = ii->filename;
  if ((NULL == fn) || (0 != ACCESS (fn, R_OK)))
  {
    GNUNET_STATISTICS_update (GSF_stats,
                              gettext_noop
                              ("# index blocks removed: original file inaccessible"),
                              1, GNUNET_YES);
    GNUNET_DATASTORE_remove (dsh, key, size, data, -1, -1,
                             GNUNET_TIME_UNIT_FOREVER_REL, &remove_cont, NULL);
    return GNUNET_SYSERR;
  }
  if ((NULL ==
       (fh =
        GNUNET_DISK_file_open (fn, GNUNET_DISK_OPEN_READ,
                               GNUNET_DISK_PERM_NONE))) ||
      (off != GNUNET_DISK_file_seek (fh, off, GNUNET_DISK_SEEK_SET)) ||
      (-1 == (nsize = GNUNET_DISK_file_read (fh, ndata, sizeof (ndata)))))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                _
                ("Could not access indexed file `%s' (%s) at offset %llu: %s\n"),
                GNUNET_h2s (&odb->file_id), fn, (unsigned long long) off,
                (fn == NULL) ? _("not indexed") : STRERROR (errno));
    if (fh != NULL)
      GNUNET_DISK_file_close (fh);
    GNUNET_DATASTORE_remove (dsh, key, size, data, -1, -1,
                             GNUNET_TIME_UNIT_FOREVER_REL, &remove_cont, NULL);
    return GNUNET_SYSERR;
  }
  GNUNET_DISK_file_close (fh);
  GNUNET_CRYPTO_hash (ndata, nsize, &nkey);
  GNUNET_CRYPTO_hash_to_aes_key (&nkey, &skey, &iv);
  GNUNET_CRYPTO_aes_encrypt (ndata, nsize, &skey, &iv, edata);
  GNUNET_CRYPTO_hash (edata, nsize, &query);
  if (0 != memcmp (&query, key, sizeof (struct GNUNET_HashCode)))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                _("Indexed file `%s' changed at offset %llu\n"), fn,
                (unsigned long long) off);
    GNUNET_DATASTORE_remove (dsh, key, size, data, -1, -1,
                             GNUNET_TIME_UNIT_FOREVER_REL, &remove_cont, NULL);
    return GNUNET_SYSERR;
  }
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "On-demand encoded block for query `%s'\n", GNUNET_h2s (key));
  cont (cont_cls, key, nsize, edata, GNUNET_BLOCK_TYPE_FS_DBLOCK, priority,
        anonymity, expiration, uid);
  return GNUNET_OK;
}
/**
 * Load a bloom-filter from a file.
 *
 * @param filename the name of the file (or the prefix)
 * @param size the size of the bloom-filter (number of
 *        bytes of storage space to use); will be rounded up
 *        to next power of 2
 * @param k the number of GNUNET_CRYPTO_hash-functions to apply per
 *        element (number of bits set per element in the set)
 * @return the bloomfilter
 */
struct GNUNET_CONTAINER_BloomFilter *
GNUNET_CONTAINER_bloomfilter_load (const char *filename, size_t size,
                                   unsigned int k)
{
  struct GNUNET_CONTAINER_BloomFilter *bf;
  char *rbuff;
  OFF_T pos;
  int i;
  size_t ui;
  OFF_T fsize;
  int must_read;

  GNUNET_assert (NULL != filename);
  if ((k == 0) || (size == 0))
    return NULL;
  if (size < BUFFSIZE)
    size = BUFFSIZE;
  ui = 1;
  while ( (ui < size) &&
	  (ui * 2 > ui) )
    ui *= 2;
  size = ui;                    /* make sure it's a power of 2 */

  bf = GNUNET_malloc (sizeof (struct GNUNET_CONTAINER_BloomFilter));
  /* Try to open a bloomfilter file */
  if (GNUNET_YES == GNUNET_DISK_file_test (filename))
    bf->fh =
      GNUNET_DISK_file_open (filename,
                             GNUNET_DISK_OPEN_READWRITE,
                             GNUNET_DISK_PERM_USER_READ |
                             GNUNET_DISK_PERM_USER_WRITE);
  if (NULL != bf->fh)
  {
    /* file existed, try to read it! */
    must_read = GNUNET_YES;
    if (GNUNET_OK !=
	GNUNET_DISK_file_handle_size (bf->fh, &fsize))
    {
      GNUNET_DISK_file_close (bf->fh);
      GNUNET_free (bf);
      return NULL;
    }
    if (fsize == 0)
    {
      /* found existing empty file, just overwrite */
      if (GNUNET_OK != make_empty_file (bf->fh, size * 4LL))
      {
	GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
			     "write");
	GNUNET_DISK_file_close (bf->fh);
	GNUNET_free (bf);
	return NULL;
      }
    }
    else if (fsize != size * 4LL)
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
		  _("Size of file on disk is incorrect for this Bloom filter (want %llu, have %llu)\n"),
		  (unsigned long long) (size * 4LL),
		  (unsigned long long) fsize);
      GNUNET_DISK_file_close (bf->fh);
      GNUNET_free (bf);
      return NULL;
    }
  }
  else
  {
    /* file did not exist, don't read, just create */
    must_read = GNUNET_NO;
    bf->fh =
      GNUNET_DISK_file_open (filename,
                             GNUNET_DISK_OPEN_CREATE |
                             GNUNET_DISK_OPEN_READWRITE,
                             GNUNET_DISK_PERM_USER_READ |
                             GNUNET_DISK_PERM_USER_WRITE);
    if (NULL == bf->fh)
      {
	GNUNET_free (bf);
	return NULL;
      }
    if (GNUNET_OK != make_empty_file (bf->fh, size * 4LL))
    {
      GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
			   "write");
      GNUNET_DISK_file_close (bf->fh);
      GNUNET_free (bf);
      return NULL;
    }
  }
  bf->filename = GNUNET_strdup (filename);
  /* Alloc block */
  bf->bitArray = GNUNET_malloc_large (size);
  if (bf->bitArray == NULL)
  {
    if (bf->fh != NULL)
      GNUNET_DISK_file_close (bf->fh);
    GNUNET_free (bf->filename);
    GNUNET_free (bf);
    return NULL;
  }
  bf->bitArraySize = size;
  bf->addressesPerElement = k;
  if (GNUNET_YES != must_read)      
    return bf; /* already done! */  
  /* Read from the file what bits we can */
  rbuff = GNUNET_malloc (BUFFSIZE);
  pos = 0;
  while (pos < size * 8LL)
  {
    int res;

    res = GNUNET_DISK_file_read (bf->fh, rbuff, BUFFSIZE);
    if (res == -1)
    {
      LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "read", bf->filename);
      GNUNET_free (rbuff);
      GNUNET_free (bf->filename);
      GNUNET_DISK_file_close (bf->fh);
      GNUNET_free (bf);
      return NULL;
    }
    if (res == 0)
      break;                    /* is ok! we just did not use that many bits yet */
    for (i = 0; i < res; i++)
    {
      if ((rbuff[i] & 0x0F) != 0)
        setBit (bf->bitArray, pos + i * 2);
      if ((rbuff[i] & 0xF0) != 0)
        setBit (bf->bitArray, pos + i * 2 + 1);
    }
    if (res < BUFFSIZE)
      break;
    pos += BUFFSIZE * 2;        /* 2 bits per byte in the buffer */
  }
  GNUNET_free (rbuff);
  return bf;
}
Esempio n. 15
0
/**
 * Initialize the database connections and associated
 * data structures (create tables and indices
 * as needed as well).
 *
 * @param plugin the plugin context (state for this module)
 * @return GNUNET_OK on success
 */
static int
database_setup (struct Plugin *plugin)
{
  char *afsdir;
  char *key;
  char *sub_system;
  const char *peer_id;
  char *peer;
  char *value;
  char *expiry;
  struct GNUNET_DISK_FileHandle *fh;
  struct GNUNET_PEERSTORE_Record *entry;
  struct GNUNET_HashCode hkey;
  size_t size;
  char *buffer;
  char *line;

  if (GNUNET_OK !=
      GNUNET_CONFIGURATION_get_value_filename (plugin->cfg, "peerstore-flat",
                                               "FILENAME", &afsdir))
  {
    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "peerstore-flat",
                               "FILENAME");
    return GNUNET_SYSERR;
  }
  if (GNUNET_OK != GNUNET_DISK_file_test (afsdir))
  {
    if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (afsdir))
    {
      GNUNET_break (0);
      GNUNET_free (afsdir);
      return GNUNET_SYSERR;
    }
  }
  /* afsdir should be UTF-8-encoded. If it isn't, it's a bug */
  plugin->fn = afsdir;

  fh = GNUNET_DISK_file_open (afsdir,
                              GNUNET_DISK_OPEN_CREATE |
                              GNUNET_DISK_OPEN_READWRITE,
                              GNUNET_DISK_PERM_USER_WRITE |
                              GNUNET_DISK_PERM_USER_READ);
  if (NULL == fh)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("Unable to initialize file: %s.\n"),
                afsdir);
    return GNUNET_SYSERR;
  }

  /* Load data from file into hashmap */
  plugin->hm = GNUNET_CONTAINER_multihashmap_create (10,
                                                     GNUNET_NO);

  if (GNUNET_SYSERR == GNUNET_DISK_file_size (afsdir,
                                              &size,
                                              GNUNET_YES,
                                              GNUNET_YES))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("Unable to get filesize: %s.\n"),
                afsdir);
    return GNUNET_SYSERR;
  }

  buffer = GNUNET_malloc (size + 1);

  if (GNUNET_SYSERR == GNUNET_DISK_file_read (fh,
                                              buffer,
                                              size))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("Unable to read file: %s.\n"),
                afsdir);
    GNUNET_DISK_file_close (fh);
    GNUNET_free (buffer);
    return GNUNET_SYSERR;
  }
  
  buffer[size] = '\0';
  GNUNET_DISK_file_close (fh);
  if (0 < size) {
    line = strtok (buffer, "\n");
    while (line != NULL) {
      sub_system = strtok (line, ",");
      if (NULL == sub_system)
        break;
      peer = strtok (NULL, ",");
      if (NULL == peer)
        break;
      key = strtok (NULL, ",");
      if (NULL == key)
        break;
      value = strtok (NULL, ",");
      if (NULL == value)
        break;
      expiry = strtok (NULL, ",");
      if (NULL == expiry)
        break;
      entry = GNUNET_new (struct GNUNET_PEERSTORE_Record);
      entry->sub_system = GNUNET_strdup (sub_system);
      entry->key = GNUNET_strdup (key);
      GNUNET_STRINGS_base64_decode (peer,
                                    strlen (peer),
                                    (char**)&entry->peer);
      entry->value_size = GNUNET_STRINGS_base64_decode (value,
                                                        strlen (value),
                                                        (char**)&entry->value);
      if (GNUNET_SYSERR == GNUNET_STRINGS_fancy_time_to_absolute (expiry,
                                             entry->expiry))
      {
        GNUNET_free (entry->sub_system);
        GNUNET_free (entry->key);
        GNUNET_free (entry->peer);
        GNUNET_free (entry);
        break;
      }
      peer_id = GNUNET_i2s (entry->peer);
      GNUNET_CRYPTO_hash (peer_id,
                          strlen (peer_id),
                          &hkey);

      GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (plugin->hm,
                                         &hkey,
                                         entry,
                                         GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));

    }
  }
/**
 * Callback function invoked for each interface found.
 *
 * @param cls closure with the `struct Plugin`
 * @param name name of the interface (can be NULL for unknown)
 * @param isDefault is this presumably the default interface
 * @param addr address of this interface (can be NULL for unknown or unassigned)
 * @param broadcast_addr the broadcast address (can be NULL for unknown or unassigned)
 * @param netmask the network mask (can be NULL for unknown or unassigned)
 * @param addrlen length of the address
 * @return #GNUNET_OK to continue iteration, #GNUNET_SYSERR to abort
 */
static int
iface_proc (void *cls,
            const char *name,
            int isDefault,
            const struct sockaddr *addr,
            const struct sockaddr *broadcast_addr,
            const struct sockaddr *netmask, socklen_t addrlen)
{
  struct Plugin *plugin = cls;
  struct BroadcastAddress *ba;
  enum GNUNET_ATS_Network_Type network;

  if (NULL == addr)
    return GNUNET_OK;
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "address %s for interface %s %p\n ",
              GNUNET_a2s (addr, addrlen), name, addr);
  if (NULL == broadcast_addr)
    return GNUNET_OK;
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "broadcast address %s for interface %s %p\n ",
              GNUNET_a2s (broadcast_addr, addrlen), name, broadcast_addr);
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "netmask %s for interface %s %p\n ",
              GNUNET_a2s (netmask, addrlen), name, netmask);

  network = plugin->env->get_address_type (plugin->env->cls, broadcast_addr, addrlen);
  if (GNUNET_ATS_NET_LOOPBACK == network)
  {
    /* Broadcasting on loopback does not make sense */
    return GNUNET_YES;
  }

  ba = GNUNET_new (struct BroadcastAddress);
  ba->plugin = plugin;
  ba->addr = GNUNET_malloc (addrlen);
  GNUNET_memcpy (ba->addr, broadcast_addr, addrlen);
  ba->addrlen = addrlen;

  if ( (GNUNET_YES == plugin->enable_ipv4) &&
       (NULL != plugin->sockv4) &&
       (addrlen == sizeof (struct sockaddr_in)) )
  {
#if LINUX
    /*
     * setup Cryogenic FD for ipv4 broadcasting
     */
    char *filename;

    GNUNET_asprintf (&filename,
                     "/dev/cryogenic/%s",
                     name);
    if (0 == ACCESS (name, R_OK))
    {
      ba->cryogenic_fd =
        GNUNET_DISK_file_open (filename,
                               GNUNET_DISK_OPEN_WRITE,
                               GNUNET_DISK_PERM_NONE);
    }
    GNUNET_free (filename);
#endif
    ba->broadcast_task =
        GNUNET_SCHEDULER_add_now (&udp_ipv4_broadcast_send, ba);
  }
  if ((GNUNET_YES == plugin->enable_ipv6) &&
      (NULL != plugin->sockv6) &&
      (addrlen == sizeof (struct sockaddr_in6)))
  {
    /* Create IPv6 multicast request */
    struct ipv6_mreq multicastRequest;
    const struct sockaddr_in6 *s6 = (const struct sockaddr_in6 *) broadcast_addr;

    multicastRequest.ipv6mr_multiaddr =
        plugin->ipv6_multicast_address.sin6_addr;
    /* http://tools.ietf.org/html/rfc2553#section-5.2:
     *
     * IPV6_JOIN_GROUP
     *
     * Join a multicast group on a specified local interface.  If the
     * interface index is specified as 0, the kernel chooses the local
     * interface.  For example, some kernels look up the multicast
     * group in the normal IPv6 routing table and using the resulting
     * interface; we do this for each interface, so no need to use
     * zero (anymore...).
     */
    multicastRequest.ipv6mr_interface = s6->sin6_scope_id;

    /* Join the multicast group */
    if (GNUNET_OK !=
        GNUNET_NETWORK_socket_setsockopt
        (plugin->sockv6, IPPROTO_IPV6, IPV6_JOIN_GROUP,
         &multicastRequest, sizeof (multicastRequest)))
    {
      LOG (GNUNET_ERROR_TYPE_WARNING,
      "Failed to join IPv6 multicast group: IPv6 broadcasting not running\n");
    }
    else
    {
#if LINUX
      /*
       * setup Cryogenic FD for ipv6 broadcasting
       */
      char *filename;

      GNUNET_asprintf (&filename,
                       "/dev/cryogenic/%s",
                       name);
      if (0 == ACCESS (name, R_OK))
      {
        ba->cryogenic_fd =
          GNUNET_DISK_file_open (filename,
                                 GNUNET_DISK_OPEN_WRITE,
                                 GNUNET_DISK_PERM_NONE);
      }
      GNUNET_free (filename);
#endif
      ba->broadcast_task =
          GNUNET_SCHEDULER_add_now (&udp_ipv6_broadcast_send, ba);
    }
  }
  GNUNET_CONTAINER_DLL_insert (plugin->broadcast_head,
                               plugin->broadcast_tail, ba);
  return GNUNET_OK;
}
Esempio n. 17
0
/**
 * Initialize the database connections and associated
 * data structures (create tables and indices
 * as needed as well).
 *
 * @param plugin the plugin context (state for this module)
 * @return #GNUNET_OK on success
 */
static int
database_setup (struct Plugin *plugin)
{
  char *afsdir;
  char* block_buffer;
  char* buffer;
  char* line;
  char* query;
  char* block;
  size_t size;
  struct FlatFileEntry *entry;
  struct GNUNET_DISK_FileHandle *fh;

  if (GNUNET_OK !=
      GNUNET_CONFIGURATION_get_value_filename (plugin->cfg, "namecache-flat",
                                               "FILENAME", &afsdir))
  {
    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
                               "namecache-flat", "FILENAME");
    return GNUNET_SYSERR;
  }
  if (GNUNET_OK != GNUNET_DISK_file_test (afsdir))
  {
    if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (afsdir))
    {
      GNUNET_break (0);
      GNUNET_free (afsdir);
      return GNUNET_SYSERR;
    }
  }
  /* afsdir should be UTF-8-encoded. If it isn't, it's a bug */
  plugin->fn = afsdir;

  /* Load data from file into hashmap */
  plugin->hm = GNUNET_CONTAINER_multihashmap_create (10,
                                                     GNUNET_NO);
  fh = GNUNET_DISK_file_open (afsdir,
                              GNUNET_DISK_OPEN_CREATE |
                              GNUNET_DISK_OPEN_READWRITE,
                              GNUNET_DISK_PERM_USER_WRITE |
                              GNUNET_DISK_PERM_USER_READ);
  if (NULL == fh)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("Unable to initialize file: %s.\n"),
                afsdir);
    return GNUNET_SYSERR;
  }

  if (GNUNET_SYSERR == GNUNET_DISK_file_size (afsdir,
                                              &size,
                                              GNUNET_YES,
                                              GNUNET_YES))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("Unable to get filesize: %s.\n"),
                afsdir);
    return GNUNET_SYSERR;
  }

  if (0 == size)
    return GNUNET_OK;

  buffer = GNUNET_malloc (size);

  if (GNUNET_SYSERR == GNUNET_DISK_file_read (fh,
                                              buffer,
                                              size))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("Unable to read file: %s.\n"),
                afsdir);
    return GNUNET_SYSERR;
  }

  GNUNET_DISK_file_close (fh);
  if (0 < size) {
    line = strtok (buffer, "\n");
    while (line != NULL) {
      query = strtok (line, ",");
      if (NULL == query)
        break;
      block = strtok (NULL, ",");
      if (NULL == block)
        break;
      line = strtok (NULL, "\n");
      entry = GNUNET_malloc (sizeof (struct FlatFileEntry));
      GNUNET_CRYPTO_hash_from_string (query,
                                      &entry->query);
      GNUNET_STRINGS_base64_decode (block,
                                    strlen (block),
                                    &block_buffer);
      entry->block = (struct GNUNET_GNSRECORD_Block *) block_buffer;
      if (GNUNET_OK != 
          GNUNET_CONTAINER_multihashmap_put (plugin->hm,
                                             &entry->query,
                                             entry,
                                             GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
      {
        GNUNET_free (entry);
        GNUNET_break (0);
      }
    }
  }
  GNUNET_free (buffer);
  return GNUNET_OK;
}
Esempio n. 18
0
/**
 * Create a new private key by reading it from a file.  If the
 * files does not exist, create a new key and write it to the
 * file.  Caller must free return value.  Note that this function
 * can not guarantee that another process might not be trying
 * the same operation on the same file at the same time.
 * If the contents of the file
 * are invalid the old file is deleted and a fresh key is
 * created.
 *
 * @param filename name of file to use to store the key
 * @return new private key, NULL on error (for example,
 *   permission denied)
 */
struct GNUNET_CRYPTO_EddsaPrivateKey *
GNUNET_CRYPTO_eddsa_key_create_from_file (const char *filename)
{
  struct GNUNET_CRYPTO_EddsaPrivateKey *priv;
  struct GNUNET_DISK_FileHandle *fd;
  unsigned int cnt;
  int ec;
  uint64_t fs;

  if (GNUNET_SYSERR == GNUNET_DISK_directory_create_for_file (filename))
    return NULL;
  while (GNUNET_YES != GNUNET_DISK_file_test (filename))
  {
    fd = GNUNET_DISK_file_open (filename,
                                GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE
                                | GNUNET_DISK_OPEN_FAILIFEXISTS,
                                GNUNET_DISK_PERM_USER_READ |
                                GNUNET_DISK_PERM_USER_WRITE);
    if (NULL == fd)
    {
      if (EEXIST == errno)
      {
        if (GNUNET_YES != GNUNET_DISK_file_test (filename))
        {
          /* must exist but not be accessible, fail for good! */
          if (0 != ACCESS (filename, R_OK))
            LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "access", filename);
          else
            GNUNET_break (0);   /* what is going on!? */
          return NULL;
        }
        continue;
      }
      LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "open", filename);
      return NULL;
    }
    cnt = 0;
    while (GNUNET_YES !=
           GNUNET_DISK_file_lock (fd, 0,
                                  sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey),
                                  GNUNET_YES))
    {
      short_wait ();
      if (0 == ++cnt % 10)
      {
        ec = errno;
        LOG (GNUNET_ERROR_TYPE_ERROR,
             _("Could not acquire lock on file `%s': %s...\n"), filename,
             STRERROR (ec));
      }
    }
    LOG (GNUNET_ERROR_TYPE_INFO,
         _("Creating a new private key.  This may take a while.\n"));
    priv = GNUNET_CRYPTO_eddsa_key_create ();
    GNUNET_assert (NULL != priv);
    GNUNET_assert (sizeof (*priv) ==
                   GNUNET_DISK_file_write (fd, priv, sizeof (*priv)));
    GNUNET_DISK_file_sync (fd);
    if (GNUNET_YES !=
        GNUNET_DISK_file_unlock (fd, 0,
                                 sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)))
      LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
    GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd));
    return priv;
  }
  /* key file exists already, read it! */
  fd = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READ,
                              GNUNET_DISK_PERM_NONE);
  if (NULL == fd)
  {
    LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "open", filename);
    return NULL;
  }
  cnt = 0;
  while (1)
  {
    if (GNUNET_YES !=
        GNUNET_DISK_file_lock (fd, 0,
                               sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey),
                               GNUNET_NO))
    {
      if (0 == ++cnt % 60)
      {
        ec = errno;
        LOG (GNUNET_ERROR_TYPE_ERROR,
             _("Could not acquire lock on file `%s': %s...\n"), filename,
             STRERROR (ec));
        LOG (GNUNET_ERROR_TYPE_ERROR,
             _
             ("This may be ok if someone is currently generating a private key.\n"));
      }
      short_wait ();
      continue;
    }
    if (GNUNET_YES != GNUNET_DISK_file_test (filename))
    {
      /* eh, what!? File we opened is now gone!? */
      LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat", filename);
      if (GNUNET_YES !=
          GNUNET_DISK_file_unlock (fd, 0,
                                   sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)))
        LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
      GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fd));

      return NULL;
    }
    if (GNUNET_OK != GNUNET_DISK_file_size (filename, &fs, GNUNET_YES, GNUNET_YES))
      fs = 0;
    if (fs < sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey))
    {
      /* maybe we got the read lock before the key generating
       * process had a chance to get the write lock; give it up! */
      if (GNUNET_YES !=
          GNUNET_DISK_file_unlock (fd, 0,
                                   sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)))
        LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
      if (0 == ++cnt % 10)
      {
        LOG (GNUNET_ERROR_TYPE_ERROR,
             _("When trying to read key file `%s' I found %u bytes but I need at least %u.\n"),
             filename, (unsigned int) fs,
             (unsigned int) sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey));
        LOG (GNUNET_ERROR_TYPE_ERROR,
             _("This may be ok if someone is currently generating a key.\n"));
      }
      short_wait ();                /* wait a bit longer! */
      continue;
    }
    break;
  }
  fs = sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey);
  priv = GNUNET_malloc (fs);
  GNUNET_assert (fs == GNUNET_DISK_file_read (fd, priv, fs));
  if (GNUNET_YES !=
      GNUNET_DISK_file_unlock (fd, 0,
                               sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)))
    LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
  GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd));
  return priv;
}
Esempio n. 19
0
void
GNUNET_ATS_TEST_logging_write_to_file (struct LoggingHandle *l,
    char *experiment_name, int plots)
{
  struct GNUNET_DISK_FileHandle *f[l->num_slaves];
  struct GNUNET_DISK_FileHandle *f_m;
  char *tmp_exp_name;
  char *filename_master;
  char *filename_slaves[l->num_slaves];
  char *data;
  struct PeerLoggingTimestep *cur_lt;
  struct PartnerLoggingTimestep *plt;
  struct GNUNET_TIME_Absolute timestamp;
  int c_m;
  int c_s;


  timestamp = GNUNET_TIME_absolute_get();

  tmp_exp_name = experiment_name;
  for (c_m = 0; c_m < l->num_masters; c_m++)
  {
    GNUNET_asprintf (&filename_master, "%s_%llu_master%u_%s",
        experiment_name, timestamp.abs_value_us, c_m, l->name);
    fprintf (stderr, "Writing data for master %u to file `%s'\n",
        c_m,filename_master);

    f_m = GNUNET_DISK_file_open (filename_master,
        GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE,
        GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE);
    if (NULL == f_m)
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot open log file `%s'\n", filename_master);
      GNUNET_free (filename_master);
      return;
    }

    GNUNET_asprintf (&data, "# master %u; experiment : %s\n"
        "timestamp; timestamp delta; #messages sent; #bytes sent; #throughput sent; #messages received; #bytes received; #throughput received; \n" ,
        c_m,  experiment_name);
    if (GNUNET_SYSERR == GNUNET_DISK_file_write(f_m, data, strlen(data)))
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
          "Cannot write data to log file `%s'\n",filename_master);
    GNUNET_free (data);

    for (c_s = 0; c_s < l->lp[c_m].peer->num_partners; c_s++)
    {
      GNUNET_asprintf (&filename_slaves[c_s], "%s_%llu_master%u_slave_%u_%s",
          tmp_exp_name, timestamp.abs_value_us, c_m, c_s, l->name);

      fprintf (stderr, "Writing data for master %u slave %u to file `%s'\n",
          c_m, c_s, filename_slaves[c_s]);

      f[c_s] = GNUNET_DISK_file_open (filename_slaves[c_s],
          GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE,
          GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE);
      if (NULL == f[c_s])
      {
        GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot open log file `%s'\n", filename_slaves[c_s]);
        GNUNET_free (filename_slaves[c_s]);
        GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close(f_m));
        GNUNET_free (filename_master);
        return;
      }

      /* Header */
      GNUNET_asprintf (&data, "# master %u; slave %u ; experiment : %s\n"
          "timestamp; timestamp delta; #messages sent; #bytes sent; #throughput sent; #messages received; #bytes received; #throughput received; " \
          "rtt; bw in; bw out; ats_cost_lan; ats_cost_wlan; ats_delay; ats_distance; ats_network_type; ats_utilization_up ;ats_utilization_down;" \
          "pref bandwidth; pref delay\n",
          c_m, c_s, experiment_name);
      if (GNUNET_SYSERR == GNUNET_DISK_file_write(f[c_s], data, strlen(data)))
        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
            "Cannot write data to log file `%s'\n",filename_slaves[c_s]);
      GNUNET_free (data);
    }

    for (cur_lt = l->lp[c_m].head; NULL != cur_lt; cur_lt = cur_lt->next)
    {
      if (l->verbose)
        fprintf (stderr,
           "Master [%u]: timestamp %llu %llu ; %u %u %u ; %u %u %u\n",
           l->lp[c_m].peer->no,
           (long long unsigned int) cur_lt->timestamp.abs_value_us,
           (long long unsigned int) GNUNET_TIME_absolute_get_difference(l->lp[c_m].start,
               cur_lt->timestamp).rel_value_us / 1000,
           cur_lt->total_messages_sent,
           cur_lt->total_bytes_sent,
           cur_lt->total_throughput_send,
           cur_lt->total_messages_received,
           cur_lt->total_bytes_received,
           cur_lt->total_throughput_recv);

      /* Assembling master string */
      GNUNET_asprintf (&data, "%llu;%llu;%u;%u;%u;%u;%u;%u;\n",
          (long long unsigned int) cur_lt->timestamp.abs_value_us,
          (long long unsigned int) GNUNET_TIME_absolute_get_difference(l->lp[c_m].start,
              cur_lt->timestamp).rel_value_us / 1000,
          cur_lt->total_messages_sent,
          cur_lt->total_bytes_sent,
          cur_lt->total_throughput_send,
          cur_lt->total_messages_received,
          cur_lt->total_bytes_received,
          cur_lt->total_throughput_recv);

      if (GNUNET_SYSERR == GNUNET_DISK_file_write(f_m, data, strlen(data)))
        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
            "Cannot write data to master file %u\n", c_m);
      GNUNET_free (data);


      for (c_s = 0; c_s < l->lp[c_m].peer->num_partners; c_s++)
      {
        plt = &cur_lt->slaves_log[c_s];
        /* Log partners */

        /* Assembling slave string */
        GNUNET_asprintf(&data,
            "%llu;%llu;%u;%u;%u;%u;%u;%u;%.3f;%u;%u;%u;%u;%u;%u;%u;%.3f;%.3f\n",
            (long long unsigned int) cur_lt->timestamp.abs_value_us,
            (long long unsigned int) GNUNET_TIME_absolute_get_difference(l->lp[c_m].start,
                cur_lt->timestamp).rel_value_us / 1000,
            plt->total_messages_sent,
            plt->total_bytes_sent,
            plt->throughput_sent,
            plt->total_messages_received,
            plt->total_bytes_received,
            plt->throughput_recv,
            (double) plt->app_rtt / 1000,
            plt->bandwidth_in,
            plt->bandwidth_out,
            plt->ats_delay,
            plt->ats_distance,
            plt->ats_network_type,
            plt->ats_utilization_out,
            plt->ats_utilization_in,
            plt->pref_bandwidth,
            plt->pref_delay);

        if (l->verbose)
          fprintf (stderr,
              "\t Slave [%u]: %u %u %u ; %u %u %u rtt %u delay %llu bw_in %u bw_out %u \n",
              plt->slave->no,
              plt->total_messages_sent,
              plt->total_bytes_sent,
              plt->throughput_sent,
              plt->total_messages_received,
              plt->total_bytes_received,
              plt->throughput_recv,
              plt->app_rtt,
              (long long unsigned int) plt->ats_delay.rel_value_us,
              plt->bandwidth_in,
              plt->bandwidth_out);

        if (GNUNET_SYSERR == GNUNET_DISK_file_write(f[c_s], data, strlen(data)))
          GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
              "Cannot write data to log file `%s'\n", filename_slaves[c_s]);
        GNUNET_free (data);

      }
    }

    for (c_s = 0; c_s < l->lp[c_m].peer->num_partners; c_s++)
    {
      if (GNUNET_SYSERR == GNUNET_DISK_file_close(f[c_s]))
      {
        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
            "Cannot close log file for master[%u] slave[%u]\n", c_m, c_s);
        continue;
      }
      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
          "Data file successfully written to log file for `%s'\n",
          filename_slaves[c_s]);
    }

    if (GNUNET_SYSERR == GNUNET_DISK_file_close(f_m))
    {
      GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
                                "close",
                                filename_master);
      GNUNET_free (filename_master);
      return;
    }
    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
        "Data file successfully written to log file for master `%s'\n", filename_master);

    if (GNUNET_YES == plots)
    {
      write_throughput_gnuplot_script (filename_master, &l->lp[c_m], filename_slaves, l->num_slaves);
      write_rtt_gnuplot_script (filename_master, &l->lp[c_m], filename_slaves, l->num_slaves);
      write_bw_gnuplot_script (filename_master, &l->lp[c_m], filename_slaves, l->num_slaves);
    }
  }
  GNUNET_free (filename_master);
}
Esempio n. 20
0
int
main (int argc, char *argv[])
{
  struct GNUNET_DISK_FileHandle *fh;
  struct GNUNET_HELLO_Message *orig;
  struct GNUNET_HELLO_Message *result;
  struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pk;
  uint64_t fsize;

  GNUNET_log_setup ("gnunet-hello", "INFO", NULL);
  if (argc != 2)
  {
    FPRINTF (stderr,
	     "%s",
	     _("Call with name of HELLO file to modify.\n"));
    return 1;
  }
  if (GNUNET_OK != GNUNET_DISK_file_size (argv[1], &fsize, GNUNET_YES, GNUNET_YES))
  {
    FPRINTF (stderr,
	     _("Error accessing file `%s': %s\n"),
	     argv[1],
	     STRERROR (errno));
    return 1;
  }
  if (fsize > 65536)
  {
    FPRINTF (stderr,
	     _("File `%s' is too big to be a HELLO\n"),
	     argv[1]);
    return 1;
  }
  if (fsize < sizeof (struct GNUNET_MessageHeader))
  {
    FPRINTF (stderr,
	     _("File `%s' is too small to be a HELLO\n"),
	     argv[1]);
    return 1;
  }
  fh = GNUNET_DISK_file_open (argv[1], 
			      GNUNET_DISK_OPEN_READ,
			      GNUNET_DISK_PERM_USER_READ);
  if (NULL == fh)
  {
    FPRINTF (stderr,
	     _("Error opening file `%s': %s\n"),
	     argv[1],
	     STRERROR (errno));
    return 1;
  }
  {
    char buf[fsize] GNUNET_ALIGN;
    
    GNUNET_assert (fsize == 
		   GNUNET_DISK_file_read (fh, buf, fsize));
    GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh));
    orig = (struct GNUNET_HELLO_Message *) buf;
    if ( (fsize != GNUNET_HELLO_size (orig)) ||
	 (GNUNET_OK != GNUNET_HELLO_get_key (orig, &pk)) )
    {
      FPRINTF (stderr,
	       _("Did not find well-formed HELLO in file `%s'\n"),
	       argv[1]);
      return 1;
    }
    result = GNUNET_HELLO_create (&pk, &add_from_hello, &orig);
    GNUNET_assert (NULL != result);
     fh = GNUNET_DISK_file_open (argv[1], 
				 GNUNET_DISK_OPEN_WRITE,
				 GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE);
     if (NULL == fh)
     {
       FPRINTF (stderr,
		_("Error opening file `%s': %s\n"),
		argv[1],
		STRERROR (errno));
       GNUNET_free (result);
       return 1;
     }
     fsize = GNUNET_HELLO_size (result);
     if (fsize != GNUNET_DISK_file_write (fh,
					  result,
					  fsize))
     {
       FPRINTF (stderr,
		_("Error writing HELLO to file `%s': %s\n"),
		argv[1],
		STRERROR (errno));
       (void) GNUNET_DISK_file_close (fh);
       return 1;
     }
    GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh));
  }
  return 0;
}