Esempio n. 1
0
static int
testReadWrite ()
{
  char tmp[100 + 1];
  int ret;

  if (strlen (TESTSTRING) !=
      GNUNET_DISK_fn_write (".testfile", TESTSTRING, strlen (TESTSTRING),
                            GNUNET_DISK_PERM_USER_READ |
                            GNUNET_DISK_PERM_USER_WRITE))
    return 1;
  if (GNUNET_OK != GNUNET_DISK_file_test (".testfile"))
    return 1;
  ret = GNUNET_DISK_fn_read (".testfile", tmp, sizeof (tmp) - 1);
  if (ret < 0)
  {
    FPRINTF (stderr, "Error reading file `%s' in testReadWrite\n", ".testfile");
    return 1;
  }
  tmp[ret] = '\0';
  if (0 != memcmp (tmp, TESTSTRING, strlen (TESTSTRING) + 1))
  {
    FPRINTF (stderr, "Error in testReadWrite: *%s* != *%s* for file %s\n", tmp,
             TESTSTRING, ".testfile");
    return 1;
  }
  GNUNET_DISK_file_copy (".testfile", ".testfile2");
  memset (tmp, 0, sizeof (tmp));
  ret = GNUNET_DISK_fn_read (".testfile2", tmp, sizeof (tmp) - 1);
  if (ret < 0)
  {
    FPRINTF (stderr, "Error reading file `%s' in testReadWrite\n",
             ".testfile2");
    return 1;
  }
  tmp[ret] = '\0';
  if (0 != memcmp (tmp, TESTSTRING, strlen (TESTSTRING) + 1))
  {
    FPRINTF (stderr, "Error in testReadWrite: *%s* != *%s* for file %s\n", tmp,
             TESTSTRING, ".testfile2");
    return 1;
  }

  GNUNET_break (0 == UNLINK (".testfile"));
  GNUNET_break (0 == UNLINK (".testfile2"));
  if (GNUNET_NO != GNUNET_DISK_file_test (".testfile"))
    return 1;

  return 0;
}
static void
removecerts (const char *file1, const char *file2)
{
    if (GNUNET_DISK_file_test (file1) == GNUNET_YES)
    {
        CHMOD (file1, S_IWUSR | S_IRUSR);
        REMOVE (file1);
    }
    if (GNUNET_DISK_file_test (file2) == GNUNET_YES)
    {
        CHMOD (file2, S_IWUSR | S_IRUSR);
        REMOVE (file2);
    }
}
/**
 * Try to read the HELLO in the given filename and discard expired addresses.
 * 
 * @param fn name of the file
 * @return HELLO of the file, NULL on error
 */
static struct GNUNET_HELLO_Message *
read_host_file (const char *fn)
{
  char buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN;
  const struct GNUNET_HELLO_Message *hello;
  struct GNUNET_HELLO_Message *hello_clean;
  int size;
  struct GNUNET_TIME_Absolute now;

  if (GNUNET_YES != GNUNET_DISK_file_test (fn))
    return NULL;
  size = GNUNET_DISK_fn_read (fn, buffer, sizeof (buffer));
  hello = (const struct GNUNET_HELLO_Message *) buffer;
  if ((size < sizeof (struct GNUNET_MessageHeader)) ||
      (size != ntohs ((((const struct GNUNET_MessageHeader *) hello)->size)))
      || (size != GNUNET_HELLO_size (hello)))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
		_("Failed to parse HELLO in file `%s'\n"),
		fn);
    return NULL;
  }
  now = GNUNET_TIME_absolute_get ();
  hello_clean =
    GNUNET_HELLO_iterate_addresses (hello, GNUNET_YES, &discard_expired,
				    &now);
  return hello_clean; 
}
Esempio n. 4
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));
}
int
main (int argc, char *argv[])
{
  int ret;

  GNUNET_DISK_directory_remove ("/tmp/test-gnunet-hostlist-peer-1");
  GNUNET_DISK_directory_remove ("/tmp/test-gnunet-hostlist-peer-2");
  GNUNET_log_setup ("test-gnunet-daemon-hostlist",
                    "WARNING",
                    NULL);
#if !WINDOWS
  system ("gnunet-peerinfo -s -c test_learning_adv_peer.conf > /dev/null");
  system ("gnunet-peerinfo -s -c test_learning_learn_peer.conf > /dev/null");
#else
  system ("gnunet-peerinfo -s -c test_learning_adv_peer.conf > NUL");
  system ("gnunet-peerinfo -s -c test_learning_learn_peer.conf > NUL");
#endif
  ret = check ();
  GNUNET_DISK_directory_remove ("/tmp/test-gnunet-hostlist-peer-1");
  GNUNET_DISK_directory_remove ("/tmp/test-gnunet-hostlist-peer-2");
  if (GNUNET_YES == GNUNET_DISK_file_test ("hostlists_learn_peer.file"))
  {
    if (0 == UNLINK ("hostlists_learn_peer.file"))
      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                  "Hostlist file hostlists_learn_peer.file was removed\n");
  }
  return ret;
}
void
delete_existing_db (const struct GNUNET_CONFIGURATION_Handle *cfg)
{
  char *afsdir;

  if (GNUNET_OK ==
      GNUNET_CONFIGURATION_get_value_filename (cfg, "namestore-sqlite",
                                               "FILENAME", &afsdir))
  {
    if (GNUNET_OK == GNUNET_DISK_file_test (afsdir))
      if (GNUNET_OK == GNUNET_DISK_file_test (afsdir))
        if (GNUNET_OK == GNUNET_DISK_directory_remove(afsdir))
          GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleted existing database `%s' \n", afsdir);
   GNUNET_free (afsdir);
  }

}
Esempio n. 7
0
/**
 * read the pseudonym infomation from a file
 * @param cfg configuration to use
 * @param nsid hash code of a pseudonym
 * @param meta meta data to be read from a file
 * @param ranking ranking of a pseudonym
 * @param ns_name name of a pseudonym
 */
static int
read_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
           const struct GNUNET_HashCode * nsid,
           struct GNUNET_CONTAINER_MetaData **meta, int32_t * ranking,
           char **ns_name)
{
  char *fn;
  char *emsg;
  struct GNUNET_BIO_ReadHandle *fileR;

  fn = get_data_filename (cfg, PS_METADATA_DIR, nsid);
  GNUNET_assert (fn != NULL);
  if (GNUNET_YES !=
      GNUNET_DISK_file_test (fn))
  {
    GNUNET_free (fn);
    return GNUNET_SYSERR;
  }
  fileR = GNUNET_BIO_read_open (fn);
  if (fileR == NULL)
  {
    GNUNET_free (fn);
    return GNUNET_SYSERR;
  }
  emsg = NULL;
  *ns_name = NULL;
  if ((GNUNET_OK != GNUNET_BIO_read_int32 (fileR, ranking)) ||
      (GNUNET_OK !=
       GNUNET_BIO_read_string (fileR, "Read string error!", ns_name, 200)) ||
      (GNUNET_OK !=
       GNUNET_BIO_read_meta_data (fileR, "Read meta data error!", meta)))
  {
    (void) GNUNET_BIO_read_close (fileR, &emsg);
    GNUNET_free_non_null (emsg);
    GNUNET_free_non_null (*ns_name);
    *ns_name = NULL;
    GNUNET_break (GNUNET_OK == GNUNET_DISK_directory_remove (fn));
    GNUNET_free (fn);
    return GNUNET_SYSERR;
  }
  if (GNUNET_OK != GNUNET_BIO_read_close (fileR, &emsg))
  {
    LOG (GNUNET_ERROR_TYPE_WARNING,
         _("Failed to parse metadata about pseudonym from file `%s': %s\n"), fn,
         emsg);
    GNUNET_break (GNUNET_OK == GNUNET_DISK_directory_remove (fn));
    GNUNET_CONTAINER_meta_data_destroy (*meta);
    *meta = NULL;
    GNUNET_free_non_null (*ns_name);
    *ns_name = NULL;
    GNUNET_free_non_null (emsg);
    GNUNET_free (fn);
    return GNUNET_SYSERR;
  }
  GNUNET_free (fn);
  return GNUNET_OK;
}
int
main (int argc, char *argv[])
{
  GNUNET_TRANSPORT_TESTING_get_test_name (argv[0], &test_name);

  GNUNET_log_setup (test_name,
                    "WARNING",
                    NULL);

  GNUNET_TRANSPORT_TESTING_get_test_source_name (__FILE__, &test_source);
  GNUNET_TRANSPORT_TESTING_get_test_plugin_name (argv[0], test_source,
                                                 &test_plugin);

  tth = GNUNET_TRANSPORT_TESTING_init ();

  GNUNET_TRANSPORT_TESTING_get_config_name (argv[0], &cfg_file_p1, 1);
  GNUNET_TRANSPORT_TESTING_get_config_name (argv[0], &cfg_file_p2, 2);

  check ();

  GNUNET_free (cfg_file_p1);
  GNUNET_free (cfg_file_p2);

  if (GNUNET_YES == GNUNET_DISK_file_test (gen_cfg_p1))
  {
    GNUNET_DISK_directory_remove (gen_cfg_p1);
    GNUNET_free (gen_cfg_p1);
  }

  if (GNUNET_YES == GNUNET_DISK_file_test (gen_cfg_p2))
  {
    GNUNET_DISK_directory_remove (gen_cfg_p2);
    GNUNET_free (gen_cfg_p2);
  }

  GNUNET_free (test_source);
  GNUNET_free (test_plugin);
  GNUNET_free (test_name);

  GNUNET_TRANSPORT_TESTING_done (tth);

  return test_failed;
}
Esempio n. 9
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. 10
0
/**
 * Handle network size estimate clients.
 *
 * @param cls closure
 * @param server the initialized server
 * @param c configuration to use
 */
static void
run (void *cls,
     const struct GNUNET_CONFIGURATION_Handle *c,
     struct GNUNET_SERVICE_Handle *service)
{
  cfg = c;
  nc = GNUNET_notification_context_create (1);
  if (GNUNET_OK !=
      GNUNET_CONFIGURATION_get_value_filename (cfg, "identity",
                                               "EGODIR",
                                               &ego_directory))
  {
    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "identity", "EGODIR");
    GNUNET_SCHEDULER_shutdown ();
    return;
  }
  if (GNUNET_OK !=
      GNUNET_CONFIGURATION_get_value_filename (cfg, "identity",
                                               "SUBSYSTEM_CFG",
                                               &subsystem_cfg_file))
  {
    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "identity", "SUBSYSTEM_CFG");
    GNUNET_SCHEDULER_shutdown ();
    return;
  }
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Loading subsystem configuration `%s'\n",
              subsystem_cfg_file);
  subsystem_cfg = GNUNET_CONFIGURATION_create ();
  if ( (GNUNET_YES ==
        GNUNET_DISK_file_test (subsystem_cfg_file)) &&
       (GNUNET_OK !=
        GNUNET_CONFIGURATION_parse (subsystem_cfg,
                                    subsystem_cfg_file)) )
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("Failed to parse subsystem identity configuration file `%s'\n"),
                subsystem_cfg_file);
    GNUNET_SCHEDULER_shutdown ();
    return;
  }
  stats = GNUNET_STATISTICS_create ("identity", cfg);
  if (GNUNET_OK !=
      GNUNET_DISK_directory_create (ego_directory))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("Failed to create directory `%s' for storing egos\n"),
                ego_directory);
  }
  GNUNET_DISK_directory_scan (ego_directory,
                              &process_ego_file,
                              NULL);
  GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
                                 NULL);
}
Esempio n. 11
0
static int
testDirMani ()
{
  if (GNUNET_OK != GNUNET_DISK_directory_create_for_file ("test/ing"))
    return 1;
  if (GNUNET_NO != GNUNET_DISK_file_test ("test"))
    return 1;
  if (GNUNET_NO != GNUNET_DISK_file_test ("test/ing"))
    return 1;
  if (GNUNET_OK != GNUNET_DISK_directory_remove ("test"))
    return 1;
  if (GNUNET_OK != GNUNET_DISK_directory_create ("test"))
    return 1;
  if (GNUNET_YES != GNUNET_DISK_directory_test ("test", GNUNET_YES))
    return 1;
  if (GNUNET_OK != GNUNET_DISK_directory_remove ("test"))
    return 1;


  return 0;
}
/**
 * Function that is called on each HELLO file in a particular directory.
 * Try to parse the file and add the HELLO to our list.
 *
 * @param cls pointer to 'unsigned int' to increment for each file, or NULL
 *            if the file is from a read-only, read-once resource directory
 * @param fullname name of the file to parse
 * @return GNUNET_OK (continue iteration)
 */
static int
hosts_directory_scan_callback (void *cls, const char *fullname)
{
  unsigned int *matched = cls;
  struct GNUNET_PeerIdentity identity;
  const char *filename;
  struct HostEntry *entry;
  struct GNUNET_HELLO_Message *hello;

  if (GNUNET_DISK_file_test (fullname) != GNUNET_YES)
    return GNUNET_OK;           /* ignore non-files */
  if (strlen (fullname) < sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded))
  {
    if (NULL != matched)
      remove_garbage (fullname);
    return GNUNET_OK;
  }
  filename =
      &fullname[strlen (fullname) -
                sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) + 1];
  if (filename[-1] != DIR_SEPARATOR)
  {
    if (NULL != matched)
      remove_garbage (fullname);
    return GNUNET_OK;
  }
  if (GNUNET_OK !=
      GNUNET_CRYPTO_hash_from_string (filename, &identity.hashPubKey))
  {
    if (NULL != (hello = read_host_file (filename)))
    {
      entry = GNUNET_malloc (sizeof (struct HostEntry));
      if (GNUNET_OK ==
	  GNUNET_HELLO_get_id (hello,
			       &entry->identity))
      {
	GNUNET_CONTAINER_multihashmap_put (hostmap, &entry->identity.hashPubKey, entry,
					   GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
	entry->hello = hello;
	notify_all (entry);
	return GNUNET_OK;
      }
      GNUNET_free (entry);
    }
    if (NULL != matched)
      remove_garbage (fullname);
    return GNUNET_OK;
  }
  if (NULL != matched)
    (*matched)++;
  add_host_to_known_hosts (&identity);
  return GNUNET_OK;
}
/**
 * Lookup the private key for the zone
 *
 * @param zone the zone we want a private key for
 * @return NULL of not found else the key
 */
struct GNUNET_CRYPTO_RsaPrivateKey*
lookup_private_key(struct GNUNET_CRYPTO_ShortHashCode *zone)
{
  char* keydir;
  struct GNUNET_CRYPTO_ShortHashAsciiEncoded zonename;
  char* location;
  struct GNUNET_CRYPTO_RsaPrivateKey *key = NULL;
  
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
              "Looking for private key\n");

  if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (GNS_cfg,
                                                            "namestore",
                                             "ZONEFILE_DIRECTORY", &keydir))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                "No zonefile directory!\n");
    return NULL;
  }

  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
              "Zonefile directory is %s\n", keydir);

  GNUNET_CRYPTO_short_hash_to_enc (zone, &zonename);

  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
              "Zonefile is %s.zkey\n", &zonename);

  GNUNET_asprintf(&location, "%s%s%s.zkey", keydir,
                  DIR_SEPARATOR_STR, &zonename);

  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
              "Checking for %s\n", location);

  if (GNUNET_YES == GNUNET_DISK_file_test (location))
    key = GNUNET_CRYPTO_rsa_key_create_from_file (location);

  GNUNET_free(location);
  GNUNET_free(keydir);

  return key;

}
static void
setup_learn_peer (struct PeerContext *p, const char *cfgname)
{
  char *filename;
  unsigned int result;
  char *binary;

  binary = GNUNET_OS_get_libexec_binary_path ("gnunet-service-arm");
  p->cfg = GNUNET_CONFIGURATION_create ();
  p->arm_proc =
    GNUNET_OS_start_process (GNUNET_YES, GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
                             NULL, NULL, NULL,
                             binary,
                             "gnunet-service-arm",
                             "-c", cfgname, NULL);
  GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname));
  if (GNUNET_OK ==
      GNUNET_CONFIGURATION_get_value_string (p->cfg, "HOSTLIST", "HOSTLISTFILE",
                                             &filename))
  {
    if (GNUNET_YES == GNUNET_DISK_file_test (filename))
    {
      result = UNLINK (filename);
      if (result == 0)
        GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                    _("Hostlist file `%s' was removed\n"), filename);
    }
    GNUNET_free (filename);
  }
  p->core =
      GNUNET_CORE_connect (p->cfg, NULL, NULL, NULL, NULL, NULL, GNUNET_NO,
                           NULL, GNUNET_NO, learn_handlers);
  GNUNET_assert (NULL != p->core);
  p->stats = GNUNET_STATISTICS_create ("hostlist", p->cfg);
  GNUNET_assert (NULL != p->stats);
  GNUNET_free (binary);
}
/**
 * Read index information from disk.
 */
static void
read_index_list ()
{
  struct GNUNET_BIO_ReadHandle *rh;
  char *fn;
  struct IndexInfo *pos;
  char *fname;
  struct GNUNET_HashCode hc;
  size_t slen;
  char *emsg;

  if (GNUNET_OK !=
      GNUNET_CONFIGURATION_get_value_filename (cfg, "FS", "INDEXDB", &fn))
  {
    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
			       "fs", "INDEXDB");
    return;
  }
  if (GNUNET_NO == GNUNET_DISK_file_test (fn))
  {
    /* no index info yet */
    GNUNET_free (fn);
    return;
  }
  rh = GNUNET_BIO_read_open (fn);
  if (NULL == rh)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                _("Could not open `%s'.\n"), fn);
    GNUNET_free (fn);
    return;
  }
  while ((GNUNET_OK ==
          GNUNET_BIO_read (rh, "Hash of indexed file", &hc,
                           sizeof (struct GNUNET_HashCode))) &&
         (GNUNET_OK ==
          GNUNET_BIO_read_string (rh, "Name of indexed file", &fname,
                                  1024 * 16)) && (fname != NULL))
  {
    slen = strlen (fname) + 1;
    pos = GNUNET_malloc (sizeof (struct IndexInfo) + slen);
    pos->file_id = hc;
    pos->filename = (const char *) &pos[1];
    memcpy (&pos[1], fname, slen);
    if (GNUNET_SYSERR ==
        GNUNET_CONTAINER_multihashmap_put (ifm, &pos->file_id, pos,
                                           GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
    {
      GNUNET_free (pos);
    }
    else
    {
      GNUNET_CONTAINER_DLL_insert (indexed_files_head,
				   indexed_files_tail,
				   pos);
    }
    GNUNET_free (fname);
  }
  if (GNUNET_OK != GNUNET_BIO_read_close (rh, &emsg))
    GNUNET_free (emsg);
  GNUNET_free (fn);
}
Esempio n. 16
0
/**
 * Run a standard GNUnet service startup sequence (initialize loggers
 * and configuration, parse options).
 *
 * @param argc number of command line arguments
 * @param argv command line arguments
 * @param service_name our service name
 * @param options service options
 * @param task main task of the service
 * @param task_cls closure for @a task
 * @return #GNUNET_SYSERR on error, #GNUNET_OK
 *         if we shutdown nicely
 */
int
GNUNET_SERVICE_run (int argc, char *const *argv,
                    const char *service_name,
                    enum GNUNET_SERVICE_Options options,
                    GNUNET_SERVICE_Main task,
                    void *task_cls)
{
#define HANDLE_ERROR do { GNUNET_break (0); goto shutdown; } while (0)

  int err;
  int ret;
  char *cfg_fn;
  char *opt_cfg_fn;
  char *loglev;
  char *logfile;
  int do_daemonize;
  unsigned int i;
  unsigned long long skew_offset;
  unsigned long long skew_variance;
  long long clock_offset;
  struct GNUNET_SERVICE_Context sctx;
  struct GNUNET_CONFIGURATION_Handle *cfg;
  const char *xdg;

  struct GNUNET_GETOPT_CommandLineOption service_options[] = {
    GNUNET_GETOPT_OPTION_CFG_FILE (&opt_cfg_fn),
    {'d', "daemonize", NULL,
     gettext_noop ("do daemonize (detach from terminal)"), 0,
     GNUNET_GETOPT_set_one, &do_daemonize},
    GNUNET_GETOPT_OPTION_HELP (NULL),
    GNUNET_GETOPT_OPTION_LOGLEVEL (&loglev),
    GNUNET_GETOPT_OPTION_LOGFILE (&logfile),
    GNUNET_GETOPT_OPTION_VERSION (PACKAGE_VERSION " " VCS_VERSION),
    GNUNET_GETOPT_OPTION_END
  };
  err = 1;
  do_daemonize = 0;
  logfile = NULL;
  loglev = NULL;
  opt_cfg_fn = NULL;
  xdg = getenv ("XDG_CONFIG_HOME");
  if (NULL != xdg)
    GNUNET_asprintf (&cfg_fn,
                     "%s%s%s",
                     xdg,
                     DIR_SEPARATOR_STR,
                     "gnunet.conf");
  else
    cfg_fn = GNUNET_strdup (GNUNET_DEFAULT_USER_CONFIG_FILE);
  memset (&sctx, 0, sizeof (sctx));
  sctx.options = options;
  sctx.ready_confirm_fd = -1;
  sctx.ret = GNUNET_OK;
  sctx.timeout = GNUNET_TIME_UNIT_FOREVER_REL;
  sctx.task = task;
  sctx.task_cls = task_cls;
  sctx.service_name = service_name;
  sctx.cfg = cfg = GNUNET_CONFIGURATION_create ();

  /* setup subsystems */
  ret = GNUNET_GETOPT_run (service_name, service_options, argc, argv);
  if (GNUNET_SYSERR == ret)
    goto shutdown;
  if (GNUNET_NO == ret)
  {
    err = 0;
    goto shutdown;
  }
  if (GNUNET_OK != GNUNET_log_setup (service_name, loglev, logfile))
    HANDLE_ERROR;
  if (NULL == opt_cfg_fn)
    opt_cfg_fn = GNUNET_strdup (cfg_fn);
  if (GNUNET_YES == GNUNET_DISK_file_test (opt_cfg_fn))
  {
    if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, opt_cfg_fn))
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                  _("Malformed configuration file `%s', exit ...\n"),
                  opt_cfg_fn);
      goto shutdown;
    }
  }
  else
  {
    if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, NULL))
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                  _("Malformed configuration, exit ...\n"));
      goto shutdown;
    }
    if (0 != strcmp (opt_cfg_fn, cfg_fn))
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
		  _("Could not access configuration file `%s'\n"),
		  opt_cfg_fn);
  }
  if (GNUNET_OK != setup_service (&sctx))
    goto shutdown;
  if ((1 == do_daemonize) && (GNUNET_OK != detach_terminal (&sctx)))
    HANDLE_ERROR;
  if (GNUNET_OK != set_user_id (&sctx))
    goto shutdown;
  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Service `%s' runs with configuration from `%s'\n",
       service_name,
       opt_cfg_fn);
  if ((GNUNET_OK ==
       GNUNET_CONFIGURATION_get_value_number (sctx.cfg, "TESTING",
                                              "SKEW_OFFSET", &skew_offset)) &&
      (GNUNET_OK ==
       GNUNET_CONFIGURATION_get_value_number (sctx.cfg, "TESTING",
                                              "SKEW_VARIANCE", &skew_variance)))
  {
    clock_offset = skew_offset - skew_variance;
    GNUNET_TIME_set_offset (clock_offset);
    LOG (GNUNET_ERROR_TYPE_DEBUG, "Skewing clock by %dll ms\n", clock_offset);
  }
  /* actually run service */
  err = 0;
  GNUNET_SCHEDULER_run (&service_task, &sctx);
  /* shutdown */
  if ((1 == do_daemonize) && (NULL != sctx.server))
    pid_file_delete (&sctx);
  GNUNET_free_non_null (sctx.my_handlers);

shutdown:
  if (-1 != sctx.ready_confirm_fd)
  {
    if (1 != WRITE (sctx.ready_confirm_fd, err ? "I" : "S", 1))
      LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "write");
    GNUNET_break (0 == CLOSE (sctx.ready_confirm_fd));
  }
#if HAVE_MALLINFO
  {
    char *counter;

    if ( (GNUNET_YES ==
	  GNUNET_CONFIGURATION_have_value (sctx.cfg, service_name,
					   "GAUGER_HEAP")) &&
	 (GNUNET_OK ==
	  GNUNET_CONFIGURATION_get_value_string (sctx.cfg, service_name,
						 "GAUGER_HEAP",
						 &counter)) )
    {
      struct mallinfo mi;

      mi = mallinfo ();
      GAUGER (service_name, counter, mi.usmblks, "blocks");
      GNUNET_free (counter);
    }
  }
#endif
  GNUNET_SPEEDUP_stop_ ();
  GNUNET_CONFIGURATION_destroy (cfg);
  i = 0;
  if (NULL != sctx.addrs)
    while (NULL != sctx.addrs[i])
      GNUNET_free (sctx.addrs[i++]);
  GNUNET_free_non_null (sctx.addrs);
  GNUNET_free_non_null (sctx.addrlens);
  GNUNET_free_non_null (logfile);
  GNUNET_free_non_null (loglev);
  GNUNET_free (cfg_fn);
  GNUNET_free_non_null (opt_cfg_fn);
  GNUNET_free_non_null (sctx.v4_denied);
  GNUNET_free_non_null (sctx.v6_denied);
  GNUNET_free_non_null (sctx.v4_allowed);
  GNUNET_free_non_null (sctx.v6_allowed);

  return err ? GNUNET_SYSERR : sctx.ret;
}
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 *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));

    }
  }
Esempio n. 18
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 *filename;

  if (GNUNET_OK !=
      GNUNET_CONFIGURATION_get_value_filename (plugin->cfg, "peerstore-sqlite",
                                               "FILENAME", &filename))
  {
    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "peerstore-sqlite",
                               "FILENAME");
    return GNUNET_SYSERR;
  }
  if (GNUNET_OK != GNUNET_DISK_file_test (filename))
  {
    if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (filename))
    {
      GNUNET_break (0);
      GNUNET_free (filename);
      return GNUNET_SYSERR;
    }
  }
  /* filename should be UTF-8-encoded. If it isn't, it's a bug */
  plugin->fn = filename;
  /* Open database and precompile statements */
  if (SQLITE_OK != sqlite3_open (plugin->fn, &plugin->dbh))
  {
    LOG (GNUNET_ERROR_TYPE_ERROR, _("Unable to initialize SQLite: %s.\n"),
         sqlite3_errmsg (plugin->dbh));
    return GNUNET_SYSERR;
  }
  sql_exec (plugin->dbh, "PRAGMA temp_store=MEMORY");
  sql_exec (plugin->dbh, "PRAGMA synchronous=OFF");
  sql_exec (plugin->dbh, "PRAGMA legacy_file_format=OFF");
  sql_exec (plugin->dbh, "PRAGMA auto_vacuum=INCREMENTAL");
  sql_exec (plugin->dbh, "PRAGMA encoding=\"UTF-8\"");
  sql_exec (plugin->dbh, "PRAGMA page_size=4096");
  sqlite3_busy_timeout (plugin->dbh, BUSY_TIMEOUT_MS);
  /* Create tables */
  sql_exec (plugin->dbh,
            "CREATE TABLE IF NOT EXISTS peerstoredata (\n"
            "  sub_system TEXT NOT NULL,\n" "  peer_id BLOB NOT NULL,\n"
            "  key TEXT NOT NULL,\n" "  value BLOB NULL,\n"
            "  expiry sqlite3_uint64 NOT NULL" ");");
  sqlite3_create_function (plugin->dbh, "UINT64_LT", 2, SQLITE_UTF8, NULL,
                           &sqlite3_lessthan, NULL, NULL);
  /* Create Indices */
  if (SQLITE_OK !=
      sqlite3_exec (plugin->dbh,
                    "CREATE INDEX IF NOT EXISTS peerstoredata_key_index ON peerstoredata (sub_system, peer_id, key)",
                    NULL, NULL, NULL))
  {
    LOG (GNUNET_ERROR_TYPE_ERROR, _("Unable to create indices: %s.\n"),
         sqlite3_errmsg (plugin->dbh));
    return GNUNET_SYSERR;
  }
  /* Prepare statements */

  sql_prepare (plugin->dbh,
               "INSERT INTO peerstoredata (sub_system, peer_id, key, value, expiry) VALUES (?,?,?,?,?);",
               &plugin->insert_peerstoredata);
  sql_prepare (plugin->dbh,
               "SELECT * FROM peerstoredata" " WHERE sub_system = ?",
               &plugin->select_peerstoredata);
  sql_prepare (plugin->dbh,
               "SELECT * FROM peerstoredata" " WHERE sub_system = ?"
               " AND peer_id = ?", &plugin->select_peerstoredata_by_pid);
  sql_prepare (plugin->dbh,
               "SELECT * FROM peerstoredata" " WHERE sub_system = ?"
               " AND key = ?", &plugin->select_peerstoredata_by_key);
  sql_prepare (plugin->dbh,
               "SELECT * FROM peerstoredata" " WHERE sub_system = ?"
               " AND peer_id = ?" " AND key = ?",
               &plugin->select_peerstoredata_by_all);
  sql_prepare (plugin->dbh,
               "DELETE FROM peerstoredata" " WHERE UINT64_LT(expiry, ?)",
               &plugin->expire_peerstoredata);
  sql_prepare (plugin->dbh,
               "DELETE FROM peerstoredata" " WHERE sub_system = ?"
               " AND peer_id = ?" " AND key = ?",
               &plugin->delete_peerstoredata);
  return GNUNET_OK;
}
Esempio n. 19
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 *config)
{
  struct GNUNET_CRYPTO_EddsaPrivateKey *pk;
  char *pids;

  cfg = config;

  /* load proof of work */
  if (NULL == pwfn)
  {
    if (GNUNET_OK !=
        GNUNET_CONFIGURATION_get_value_filename (cfg, "NSE",
                                                 "PROOFFILE",
                                                 &pwfn))
    {
      GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
                                 "NSE", "PROOFFILE");
      GNUNET_SCHEDULER_shutdown ();
      return;
    }
  }
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
              "Proof of Work file: %s\n",
              pwfn);
  if ( (GNUNET_YES != GNUNET_DISK_file_test (pwfn)) ||
       (sizeof (proof) !=
        GNUNET_DISK_fn_read (pwfn, &proof, sizeof (proof))))
    proof = 0;

  /* load private key */
  if (NULL == pkfn)
  {
    if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "PEER",
                                                              "PRIVATE_KEY",
                                                              &pkfn))
    {
      GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
                                 "PEER", "PRIVATE_KEY");
      return;
    }
  }
  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Private Key file: %s\n", pkfn);
  if (NULL == (pk = GNUNET_CRYPTO_eddsa_key_create_from_file (pkfn)))
  {
    FPRINTF (stderr, _("Loading hostkey from `%s' failed.\n"), pkfn);
    GNUNET_free (pkfn);
    return;
  }
  GNUNET_free (pkfn);
  GNUNET_CRYPTO_eddsa_key_get_public (pk, &pub);
  GNUNET_free (pk);
  pids = GNUNET_CRYPTO_eddsa_public_key_to_string (&pub);
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
              "Peer ID: %s\n",
              pids);
  GNUNET_free (pids);

  /* get target bit amount */
  if (0 == nse_work_required)
  {
    if (GNUNET_OK !=
        GNUNET_CONFIGURATION_get_value_number (cfg, "NSE", "WORKBITS",
                                               &nse_work_required))
    {
      GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "NSE", "WORKBITS");
      GNUNET_SCHEDULER_shutdown ();
      return;
    }
    if (nse_work_required >= sizeof (struct GNUNET_HashCode) * 8)
    {
      GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, "NSE", "WORKBITS",
                                _("Value is too large.\n"));
      GNUNET_SCHEDULER_shutdown ();
      return;
    } else if (0 == nse_work_required)
    {
      write_proof ();
      GNUNET_SCHEDULER_shutdown ();
      return;
    }
  }
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
              "Bits: %llu\n",
              nse_work_required);

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Delay between tries: %s\n",
              GNUNET_STRINGS_relative_time_to_string (proof_find_delay, 1));
  GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE,
                                      &find_proof, NULL);
}
/**
 * Read the friends file.
 */
static void
read_friends_file (const struct GNUNET_CONFIGURATION_Handle *cfg)
{
  char *fn;
  char *data;
  size_t pos;
  struct GNUNET_PeerIdentity pid;
  uint64_t fsize;
  struct GNUNET_CRYPTO_HashAsciiEncoded enc;
  unsigned int entries_found;
  struct Peer *fl;

  if (GNUNET_OK !=
      GNUNET_CONFIGURATION_get_value_filename (cfg, "TOPOLOGY", "FRIENDS", &fn))
  {
    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
			       "topology", "FRIENDS");
    return;
  }
  if (GNUNET_OK != GNUNET_DISK_file_test (fn))
    GNUNET_DISK_fn_write (fn, NULL, 0,
                          GNUNET_DISK_PERM_USER_READ |
                          GNUNET_DISK_PERM_USER_WRITE);
  if (GNUNET_OK != GNUNET_DISK_file_size (fn,
      &fsize, GNUNET_NO, GNUNET_YES))
  {
    if ((friends_only) || (minimum_friend_count > 0))
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                  _("Could not read friends list `%s'\n"), fn);
    GNUNET_free (fn);
    return;
  }
  if (fsize == 0)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Friends file `%s' is empty.\n"),
                fn);
    GNUNET_free (fn);
    return;
  }
  data = GNUNET_malloc_large (fsize);
  if (data == NULL)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("Failed to read friends list from `%s': out of memory\n"),
                fn);
    GNUNET_free (fn);
    return;
  }
  if (fsize != GNUNET_DISK_fn_read (fn, data, fsize))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("Failed to read friends list from `%s'\n"), fn);
    GNUNET_free (fn);
    GNUNET_free (data);
    return;
  }
  entries_found = 0;
  pos = 0;
  while ((pos < fsize) && isspace ((unsigned char) data[pos]))
    pos++;
  while ((fsize >= sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)) &&
         (pos <=
          fsize - sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)))
  {
    memcpy (&enc, &data[pos], sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded));
    if (!isspace
        ((unsigned char)
         enc.encoding[sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1]))
    {
      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                  _
                  ("Syntax error in topology specification at offset %llu, skipping bytes.\n"),
                  (unsigned long long) pos);
      pos++;
      while ((pos < fsize) && (!isspace ((unsigned char) data[pos])))
        pos++;
      continue;
    }
    enc.encoding[sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] = '\0';
    if (GNUNET_OK !=
        GNUNET_CRYPTO_hash_from_string ((char *) &enc, &pid.hashPubKey))
    {
      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                  _
                  ("Syntax error in topology specification at offset %llu, skipping bytes `%s'.\n"),
                  (unsigned long long) pos, &enc);
    }
    else
    {
      if (0 != memcmp (&pid, &my_identity, sizeof (struct GNUNET_PeerIdentity)))
      {
        entries_found++;
        fl = make_peer (&pid, NULL, GNUNET_YES);
        GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                    _("Found friend `%s' in configuration\n"),
                    GNUNET_i2s (&fl->pid));
      }
      else
      {
        GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                    _("Found myself `%s' in friend list (useless, ignored)\n"),
                    GNUNET_i2s (&pid));
      }
    }
    pos = pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded);
    while ((pos < fsize) && isspace ((unsigned char) data[pos]))
      pos++;
  }
  GNUNET_free (data);
  GNUNET_free (fn);
  GNUNET_STATISTICS_update (stats, gettext_noop ("# friends in configuration"),
                            entries_found, GNUNET_NO);
  if ((minimum_friend_count > entries_found) && (friends_only == GNUNET_NO))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                _
                ("Fewer friends specified than required by minimum friend count. Will only connect to friends.\n"));
  }
  if ((minimum_friend_count > target_connection_count) &&
      (friends_only == GNUNET_NO))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                _
                ("More friendly connections required than target total number of connections.\n"));
  }
}
Esempio n. 21
0
/**
 * Handle network size estimate clients.
 *
 * @param cls closure
 * @param server the initialized server
 * @param c configuration to use
 */
static void
run (void *cls,
     struct GNUNET_SERVER_Handle *server,
     const struct GNUNET_CONFIGURATION_Handle *c)
{
  static const struct GNUNET_SERVER_MessageHandler handlers[] = {
    {&handle_start_message, NULL,
     GNUNET_MESSAGE_TYPE_IDENTITY_START, sizeof (struct GNUNET_MessageHeader)},
    {&handle_get_default_message, NULL,
     GNUNET_MESSAGE_TYPE_IDENTITY_GET_DEFAULT, 0},
    {&handle_set_default_message, NULL,
     GNUNET_MESSAGE_TYPE_IDENTITY_SET_DEFAULT, 0},
    {&handle_create_message, NULL,
     GNUNET_MESSAGE_TYPE_IDENTITY_CREATE, 0},
    {&handle_rename_message, NULL,
     GNUNET_MESSAGE_TYPE_IDENTITY_RENAME, 0},
    {&handle_delete_message, NULL,
     GNUNET_MESSAGE_TYPE_IDENTITY_DELETE, 0},
    {NULL, NULL, 0, 0}
  };

  cfg = c;
  if (GNUNET_OK !=
      GNUNET_CONFIGURATION_get_value_filename (cfg, "identity",
					       "EGODIR",
					       &ego_directory))
  {
    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "identity", "EGODIR");
    GNUNET_SCHEDULER_shutdown ();
    return;
  }
  if (GNUNET_OK !=
      GNUNET_CONFIGURATION_get_value_filename (cfg, "identity",
					       "SUBSYSTEM_CFG",
					       &subsystem_cfg_file))
  {
    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "identity", "SUBSYSTEM_CFG");
    GNUNET_SCHEDULER_shutdown ();
    return;
  }
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
	      "Loading subsystem configuration `%s'\n",
	      subsystem_cfg_file);
  subsystem_cfg = GNUNET_CONFIGURATION_create ();
  if ( (GNUNET_YES ==
	GNUNET_DISK_file_test (subsystem_cfg_file)) &&
       (GNUNET_OK !=
	GNUNET_CONFIGURATION_parse (subsystem_cfg,
				    subsystem_cfg_file)) )
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
		_("Failed to parse subsystem identity configuration file `%s'\n"),
		subsystem_cfg_file);
    GNUNET_SCHEDULER_shutdown ();
    return;
  }
  stats = GNUNET_STATISTICS_create ("identity", cfg);
  GNUNET_SERVER_add_handlers (server, handlers);
  nc = GNUNET_SERVER_notification_context_create (server, 1);
  if (GNUNET_OK !=
      GNUNET_DISK_directory_create (ego_directory))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
		_("Failed to create directory `%s' for storing egos\n"),
		ego_directory);
  }
  GNUNET_DISK_directory_scan (ego_directory,
			      &process_ego_file,
			      NULL);
  GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
                                NULL);
}
/**
 * Initialize the database connections and associated
 * data structures (create tables and indices
 * as needed as well).
 *
 * @param cfg our configuration
 * @param plugin the plugin context (state for this module)
 * @return GNUNET_OK on success
 */
static int
database_setup (const struct GNUNET_CONFIGURATION_Handle *cfg,
                struct Plugin *plugin)
{
  sqlite3_stmt *stmt;
  char *afsdir;

#if ENULL_DEFINED
  char *e;
#endif

  if (GNUNET_OK !=
      GNUNET_CONFIGURATION_get_value_filename (cfg, "datastore-sqlite",
                                               "FILENAME", &afsdir))
  {
    GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "sqlite",
                     _
                     ("Option `%s' in section `%s' missing in configuration!\n"),
                     "FILENAME", "datastore-sqlite");
    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;
    }
    /* database is new or got deleted, reset payload to zero! */
    plugin->env->duc (plugin->env->cls, 0);
  }
#ifdef ENABLE_NLS
  plugin->fn =
      GNUNET_STRINGS_to_utf8 (afsdir, strlen (afsdir), nl_langinfo (CODESET));
#else
  plugin->fn = GNUNET_STRINGS_to_utf8 (afsdir, strlen (afsdir), "UTF-8");       /* good luck */
#endif
  GNUNET_free (afsdir);

  /* Open database and precompile statements */
  if (sqlite3_open (plugin->fn, &plugin->dbh) != SQLITE_OK)
  {
    GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "sqlite",
                     _("Unable to initialize SQLite: %s.\n"),
                     sqlite3_errmsg (plugin->dbh));
    return GNUNET_SYSERR;
  }
  CHECK (SQLITE_OK ==
         sqlite3_exec (plugin->dbh, "PRAGMA temp_store=MEMORY", NULL, NULL,
                       ENULL));
  CHECK (SQLITE_OK ==
         sqlite3_exec (plugin->dbh, "PRAGMA synchronous=OFF", NULL, NULL,
                       ENULL));
  CHECK (SQLITE_OK ==
         sqlite3_exec (plugin->dbh, "PRAGMA legacy_file_format=OFF", NULL, NULL,
                       ENULL));
  CHECK (SQLITE_OK ==
         sqlite3_exec (plugin->dbh, "PRAGMA auto_vacuum=INCREMENTAL", NULL,
                       NULL, ENULL));
  CHECK (SQLITE_OK ==
         sqlite3_exec (plugin->dbh, "PRAGMA locking_mode=EXCLUSIVE", NULL, NULL,
                       ENULL));
  CHECK (SQLITE_OK ==
         sqlite3_exec (plugin->dbh, "PRAGMA count_changes=OFF", NULL, NULL,
                       ENULL));
  CHECK (SQLITE_OK ==
         sqlite3_exec (plugin->dbh, "PRAGMA page_size=4092", NULL, NULL,
                       ENULL));

  CHECK (SQLITE_OK == sqlite3_busy_timeout (plugin->dbh, BUSY_TIMEOUT_MS));


  /* We have to do it here, because otherwise precompiling SQL might fail */
  CHECK (SQLITE_OK ==
         sq_prepare (plugin->dbh,
                     "SELECT 1 FROM sqlite_master WHERE tbl_name = 'gn090'",
                     &stmt));
  if ((sqlite3_step (stmt) == SQLITE_DONE) &&
      (sqlite3_exec
       (plugin->dbh,
        "CREATE TABLE gn090 (" "  repl INT4 NOT NULL DEFAULT 0,"
        "  type INT4 NOT NULL DEFAULT 0," "  prio INT4 NOT NULL DEFAULT 0,"
        "  anonLevel INT4 NOT NULL DEFAULT 0,"
        "  expire INT8 NOT NULL DEFAULT 0," "  rvalue INT8 NOT NULL,"
        "  hash TEXT NOT NULL DEFAULT ''," "  vhash TEXT NOT NULL DEFAULT '',"
        "  value BLOB NOT NULL DEFAULT '')", NULL, NULL, NULL) != SQLITE_OK))
  {
    LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR, "sqlite3_exec");
    sqlite3_finalize (stmt);
    return GNUNET_SYSERR;
  }
  sqlite3_finalize (stmt);
  create_indices (plugin->dbh);

  if ((sq_prepare
       (plugin->dbh,
        "UPDATE gn090 "
        "SET prio = prio + ?, expire = MAX(expire,?) WHERE _ROWID_ = ?",
        &plugin->updPrio) != SQLITE_OK) ||
      (sq_prepare
       (plugin->dbh,
        "UPDATE gn090 " "SET repl = MAX (0, repl - 1) WHERE _ROWID_ = ?",
        &plugin->updRepl) != SQLITE_OK) ||
      (sq_prepare
       (plugin->dbh,
        "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ " "FROM gn090 "
#if SQLITE_VERSION_NUMBER >= 3007000
        "INDEXED BY idx_repl_rvalue "
#endif
        "WHERE repl=?2 AND " " (rvalue>=?1 OR "
        "  NOT EXISTS (SELECT 1 FROM gn090 "
#if SQLITE_VERSION_NUMBER >= 3007000
        "INDEXED BY idx_repl_rvalue "
#endif
        "WHERE repl=?2 AND rvalue>=?1 LIMIT 1) ) "
        "ORDER BY rvalue ASC LIMIT 1", &plugin->selRepl) != SQLITE_OK) ||
      (sq_prepare (plugin->dbh, "SELECT MAX(repl) FROM gn090"
#if SQLITE_VERSION_NUMBER >= 3007000
                   " INDEXED BY idx_repl_rvalue"
#endif
                   "", &plugin->maxRepl) != SQLITE_OK) ||
      (sq_prepare
       (plugin->dbh,
        "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ " "FROM gn090 "
#if SQLITE_VERSION_NUMBER >= 3007000
        "INDEXED BY idx_expire "
#endif
        "WHERE NOT EXISTS (SELECT 1 FROM gn090 WHERE expire < ?1 LIMIT 1) OR (expire < ?1) "
        "ORDER BY expire ASC LIMIT 1", &plugin->selExpi) != SQLITE_OK) ||
      (sq_prepare
       (plugin->dbh,
        "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ " "FROM gn090 "
#if SQLITE_VERSION_NUMBER >= 3007000
        "INDEXED BY idx_anon_type_hash "
#endif
        "WHERE (anonLevel = 0 AND type=?1) "
        "ORDER BY hash DESC LIMIT 1 OFFSET ?2",
        &plugin->selZeroAnon) != SQLITE_OK) ||
      (sq_prepare
       (plugin->dbh,
        "INSERT INTO gn090 (repl, type, prio, anonLevel, expire, rvalue, hash, vhash, value) "
        "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
        &plugin->insertContent) != SQLITE_OK) ||
      (sq_prepare
       (plugin->dbh, "DELETE FROM gn090 WHERE _ROWID_ = ?",
        &plugin->delRow) != SQLITE_OK))
  {
    LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR, "precompiling");
    return GNUNET_SYSERR;
  }

  return GNUNET_OK;
}
Esempio n. 23
0
/**
 * Handle network size estimate clients.
 *
 * @param cls closure
 * @param c configuration to use
 * @param service the initialized service
 */
static void
run (void *cls,
     const struct GNUNET_CONFIGURATION_Handle *c,
     struct GNUNET_SERVICE_Handle *service)
{
  struct GNUNET_MQ_MessageHandler core_handlers[] = {
    GNUNET_MQ_hd_fixed_size (p2p_estimate,
                             GNUNET_MESSAGE_TYPE_NSE_P2P_FLOOD,
                             struct GNUNET_NSE_FloodMessage,
                             NULL),
    GNUNET_MQ_handler_end ()
  };
  char *proof;
  struct GNUNET_CRYPTO_EddsaPrivateKey *pk;

  cfg = c;
  if (GNUNET_OK !=
      GNUNET_CONFIGURATION_get_value_time (cfg,
					   "NSE",
					   "INTERVAL",
					   &gnunet_nse_interval))
  {
    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
			       "NSE",
			       "INTERVAL");
    GNUNET_SCHEDULER_shutdown ();
    return;
  }
  if (GNUNET_OK !=
      GNUNET_CONFIGURATION_get_value_time (cfg,
					   "NSE",
					   "WORKDELAY",
					   &proof_find_delay))
  {
    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
			       "NSE",
			       "WORKDELAY");
    GNUNET_SCHEDULER_shutdown ();
    return;
  }
  if (GNUNET_OK !=
      GNUNET_CONFIGURATION_get_value_number (cfg,
					     "NSE",
					     "WORKBITS",
					     &nse_work_required))
  {
    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
			       "NSE",
			       "WORKBITS");
    GNUNET_SCHEDULER_shutdown ();
    return;
  }
  if (nse_work_required >= sizeof (struct GNUNET_HashCode) * 8)
  {
    GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
			       "NSE",
			       "WORKBITS",
			       _("Value is too large.\n"));
    GNUNET_SCHEDULER_shutdown ();
    return;
  }

#if ENABLE_NSE_HISTOGRAM
  {
    char *histogram_dir;
    char *histogram_fn;

    if (GNUNET_OK ==
        GNUNET_CONFIGURATION_get_value_filename (cfg,
						 "NSE",
						 "HISTOGRAM_DIR",
                                                 &histogram_dir))
    {
      GNUNET_assert (0 < GNUNET_asprintf (&histogram_fn,
					  "%s/timestamps",
                                          histogram_dir));
      GNUNET_free (histogram_dir);
      histogram = GNUNET_BIO_write_open (histogram_fn);
      if (NULL == histogram)
        GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
		    "Unable to open histogram file `%s'\n",
		    histogram_fn);
      GNUNET_free (histogram_fn);
    }
    logger_test =
        GNUNET_CLIENT_service_test ("testbed-logger",
				    cfg,
                                    GNUNET_TIME_UNIT_SECONDS,
                                    &status_cb,
				    NULL);

  }
#endif

  GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
				 NULL);
  pk = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg);
  GNUNET_assert (NULL != pk);
  my_private_key = pk;
  GNUNET_CRYPTO_eddsa_key_get_public (my_private_key,
				      &my_identity.public_key);
  if (GNUNET_OK !=
      GNUNET_CONFIGURATION_get_value_filename (cfg,
					       "NSE",
					       "PROOFFILE",
					       &proof))
  {
    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
			       "NSE",
			       "PROOFFILE");
    GNUNET_free (my_private_key);
    my_private_key = NULL;
    GNUNET_SCHEDULER_shutdown ();
    return;
  }
  if ((GNUNET_YES != GNUNET_DISK_file_test (proof)) ||
      (sizeof (my_proof) !=
       GNUNET_DISK_fn_read (proof,
			    &my_proof,
			    sizeof (my_proof))))
    my_proof = 0;
  GNUNET_free (proof);
  proof_task =
      GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE,
                                          &find_proof,
					  NULL);

  peers = GNUNET_CONTAINER_multipeermap_create (128,
						GNUNET_YES);
  nc = GNUNET_notification_context_create (1);
  /* Connect to core service and register core handlers */
  core_api = GNUNET_CORE_connect (cfg,   /* Main configuration */
				  NULL,       /* Closure passed to functions */
				  &core_init,    /* Call core_init once connected */
				  &handle_core_connect,  /* Handle connects */
				  &handle_core_disconnect,       /* Handle disconnects */
				  core_handlers);        /* Register these handlers */
  if (NULL == core_api)
  {
    GNUNET_SCHEDULER_shutdown ();
    return;
  }
  stats = GNUNET_STATISTICS_create ("nse",
				    cfg);
}
Esempio n. 24
0
/**
 * Load a set of hosts from a configuration file.
 *
 * @param filename file with the host specification
 * @param cfg the configuration to use as a template while starting a controller
 *          on any of the loaded hosts.  Operation queue sizes specific to a host
 *          are also read from this configuration handle
 * @param hosts set to the hosts found in the file; caller must free this if
 *          number of hosts returned is greater than 0
 * @return number of hosts returned in 'hosts', 0 on error
 */
unsigned int
GNUNET_TESTBED_hosts_load_from_file (const char *filename,
                                     const struct GNUNET_CONFIGURATION_Handle
                                     *cfg,
                                     struct GNUNET_TESTBED_Host ***hosts)
{
  //struct GNUNET_TESTBED_Host **host_array;
  struct GNUNET_TESTBED_Host *starting_host;
  char *data;
  char *buf;
  char *username;
  char *hostname;
  regex_t rex;
  regmatch_t pmatch[6];
  uint64_t fs;
  short int port;
  unsigned int offset;
  unsigned int count;


  GNUNET_assert (NULL != filename);
  if (GNUNET_YES != GNUNET_DISK_file_test (filename))
  {
    LOG (GNUNET_ERROR_TYPE_WARNING, _("Hosts file %s not found\n"), filename);
    return 0;
  }
  if (GNUNET_OK !=
      GNUNET_DISK_file_size (filename, &fs, GNUNET_YES, GNUNET_YES))
    fs = 0;
  if (0 == fs)
  {
    LOG (GNUNET_ERROR_TYPE_WARNING, _("Hosts file %s has no data\n"), filename);
    return 0;
  }
  data = GNUNET_malloc (fs);
  if (fs != GNUNET_DISK_fn_read (filename, data, fs))
  {
    GNUNET_free (data);
    LOG (GNUNET_ERROR_TYPE_WARNING, _("Hosts file %s cannot be read\n"),
         filename);
    return 0;
  }
  buf = data;
  offset = 0;
  starting_host = NULL;
  count = 0;
  /* refer RFC 952 and RFC 1123 for valid hostnames */
  GNUNET_assert (0 == regcomp (&rex,
                               "^(([[:alnum:]]+)@)?" /* username */
                               "([[:alnum:]]+[-[:alnum:]_\\.]+)" /* hostname */
                               "(:([[:digit:]]{1,5}))?", /* port */
                               REG_EXTENDED | REG_ICASE));
  while (offset < (fs - 1))
  {
    offset++;
    if (((data[offset] == '\n')) && (buf != &data[offset]))
    {
      unsigned int size;

      data[offset] = '\0';
      username = NULL;
      hostname = NULL;
      port = 0;
      if ((REG_NOMATCH == regexec (&rex, buf, 6, pmatch, 0))
          || (-1 == pmatch[3].rm_so))
      {
        GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                    "Error reading line `%s' in hostfile\n", buf);
        buf = &data[offset + 1];
        continue;
      }
      if (-1 != pmatch[2].rm_so)
      {
        size = pmatch[2].rm_eo - pmatch[2].rm_so;
        username = GNUNET_malloc (size + 1);
        username[size] = '\0';
        GNUNET_assert (NULL != strncpy (username, buf + pmatch[2].rm_so, size));
      }
      if (-1 != pmatch[5].rm_so)
      {
        (void) SSCANF (buf + pmatch[5].rm_so, "%5hd", &port);
      }
      size = pmatch[3].rm_eo - pmatch[3].rm_so;
      hostname = GNUNET_malloc (size + 1);
      hostname[size] = '\0';
      GNUNET_assert (NULL != strncpy (hostname, buf + pmatch[3].rm_so, size));
      LOG (GNUNET_ERROR_TYPE_DEBUG,
           "Successfully read host %s, port %d and user %s from file\n",
           (NULL == hostname) ? "NULL" : hostname,
           port,
           (NULL == username) ? "NULL" : username);
      /* We store hosts in a static list; hence we only require the starting
       * host pointer in that list to access the newly created list of hosts */
      if (NULL == starting_host)
        starting_host = GNUNET_TESTBED_host_create (hostname, username, cfg,
                                                    port);
      else
        (void) GNUNET_TESTBED_host_create (hostname, username, cfg, port);
      count++;
      GNUNET_free_non_null (username);
      GNUNET_free (hostname);
      buf = &data[offset + 1];
    }
    else if ((data[offset] == '\n') || (data[offset] == '\0'))
      buf = &data[offset + 1];
  }
  regfree (&rex);
  GNUNET_free (data);
  if (NULL == starting_host)
    return 0;
  *hosts = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_Host *) * count);
  memcpy (*hosts, &host_list[GNUNET_TESTBED_host_get_id_ (starting_host)],
          sizeof (struct GNUNET_TESTBED_Host *) * count);
  return count;
}
Esempio n. 25
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)
{
  sqlite3_stmt *stmt;
  char *afsdir;
#if ENULL_DEFINED
  char *e;
#endif

  if (GNUNET_OK !=
      GNUNET_CONFIGURATION_get_value_filename (plugin->cfg, "namecache-sqlite",
                                               "FILENAME", &afsdir))
  {
    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
			       "namecache-sqlite", "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;

  /* Open database and precompile statements */
  if (sqlite3_open (plugin->fn, &plugin->dbh) != SQLITE_OK)
  {
    LOG (GNUNET_ERROR_TYPE_ERROR,
	 _("Unable to initialize SQLite: %s.\n"),
	 sqlite3_errmsg (plugin->dbh));
    return GNUNET_SYSERR;
  }
  CHECK (SQLITE_OK ==
         sqlite3_exec (plugin->dbh, "PRAGMA temp_store=MEMORY", NULL, NULL,
                       ENULL));
  CHECK (SQLITE_OK ==
         sqlite3_exec (plugin->dbh, "PRAGMA synchronous=NORMAL", NULL, NULL,
                       ENULL));
  CHECK (SQLITE_OK ==
         sqlite3_exec (plugin->dbh, "PRAGMA legacy_file_format=OFF", NULL, NULL,
                       ENULL));
  CHECK (SQLITE_OK ==
         sqlite3_exec (plugin->dbh, "PRAGMA auto_vacuum=INCREMENTAL", NULL,
                       NULL, ENULL));
  CHECK (SQLITE_OK ==
         sqlite3_exec (plugin->dbh, "PRAGMA encoding=\"UTF-8\"", NULL,
                       NULL, ENULL));
  CHECK (SQLITE_OK ==
         sqlite3_exec (plugin->dbh, "PRAGMA locking_mode=EXCLUSIVE", NULL, NULL,
                       ENULL));
  CHECK (SQLITE_OK ==
         sqlite3_exec (plugin->dbh, "PRAGMA page_size=4092", NULL, NULL,
                       ENULL));

  CHECK (SQLITE_OK == sqlite3_busy_timeout (plugin->dbh, BUSY_TIMEOUT_MS));


  /* Create tables */
  CHECK (SQLITE_OK ==
         sq_prepare (plugin->dbh,
                     "SELECT 1 FROM sqlite_master WHERE tbl_name = 'ns096blocks'",
                     &stmt));
  if ((sqlite3_step (stmt) == SQLITE_DONE) &&
      (sqlite3_exec
       (plugin->dbh,
        "CREATE TABLE ns096blocks ("
        " query BLOB NOT NULL DEFAULT '',"
        " block BLOB NOT NULL DEFAULT '',"
        " expiration_time INT8 NOT NULL DEFAULT 0"
	")",
	NULL, NULL, NULL) != SQLITE_OK))
  {
    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite3_exec");
    sqlite3_finalize (stmt);
    return GNUNET_SYSERR;
  }
  sqlite3_finalize (stmt);
  create_indices (plugin->dbh);

  if ((sq_prepare
       (plugin->dbh,
        "INSERT INTO ns096blocks (query,block,expiration_time) VALUES (?, ?, ?)",
        &plugin->cache_block) != SQLITE_OK) ||
      (sq_prepare
       (plugin->dbh,
        "DELETE FROM ns096blocks WHERE expiration_time<?",
        &plugin->expire_blocks) != SQLITE_OK) ||
      (sq_prepare
       (plugin->dbh,
        "DELETE FROM ns096blocks WHERE query=? AND expiration_time<=?",
        &plugin->delete_block) != SQLITE_OK) ||
      (sq_prepare
       (plugin->dbh,
        "SELECT block FROM ns096blocks WHERE query=? ORDER BY expiration_time DESC LIMIT 1",
        &plugin->lookup_block) != SQLITE_OK)
      )
  {
    LOG_SQLITE (plugin,GNUNET_ERROR_TYPE_ERROR, "precompiling");
    return GNUNET_SYSERR;
  }
  return GNUNET_OK;
}
static void
run (void *cls, char *const *args, const char *cfgfile,
     const struct GNUNET_CONFIGURATION_Handle *cfg)
{
  struct GNUNET_TESTING_Host *hosts;
  struct GNUNET_TESTING_Host *hostpos;
  struct GNUNET_TESTING_Host *temphost;
  char *hostfile;
  struct stat frstat;
  char *buf;
  char *data;
  int count;
  int ret;

  ok = 1;
#if VERBOSE
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting daemons.\n");
#endif

  if (GNUNET_SYSERR ==
      GNUNET_CONFIGURATION_get_value_number (cfg, "testing", "num_peers",
                                             &num_peers))
    num_peers = DEFAULT_NUM_PEERS;

  GNUNET_assert (num_peers > 0 && num_peers < (unsigned long long) -1);
  if (GNUNET_OK !=
      GNUNET_CONFIGURATION_get_value_string (cfg, "testing", "hostfile",
                                             &hostfile))
    hostfile = NULL;

  hosts = NULL;
  data = NULL;
  if (hostfile != NULL)
  {
    if (GNUNET_OK != GNUNET_DISK_file_test (hostfile))
      GNUNET_DISK_fn_write (hostfile, NULL, 0,
                            GNUNET_DISK_PERM_USER_READ |
                            GNUNET_DISK_PERM_USER_WRITE);
    if ((0 != STAT (hostfile, &frstat)) || (frstat.st_size == 0))
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                  "Could not open file specified for host list, ending test!");
      ok = 1119;
      GNUNET_free (hostfile);
      return;
    }

    data = GNUNET_malloc_large (frstat.st_size);
    GNUNET_assert (data != NULL);
    if (frstat.st_size != GNUNET_DISK_fn_read (hostfile, data, frstat.st_size))
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                  "Could not read file %s specified for host list, ending test!",
                  hostfile);
      GNUNET_free (hostfile);
      GNUNET_free (data);
      return;
    }

    GNUNET_free_non_null (hostfile);

    buf = data;
    count = 0;
    while (count < frstat.st_size)
    {
      count++;
      if (count >= frstat.st_size)
        break;

      /* if (((data[count] == '\n') || (data[count] == '\0')) && (buf != &data[count])) */
      if (((data[count] == '\n')) && (buf != &data[count]))
      {
        data[count] = '\0';
        temphost = GNUNET_malloc (sizeof (struct GNUNET_TESTING_Host));
        ret =
            SSCANF (buf, "%a[a-zA-Z0-9]@%a[a-zA-Z0-9.]:%hd",
                    &temphost->username, &temphost->hostname, &temphost->port);
        if (3 == ret)
        {
          GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                      "Successfully read host %s, port %d and user %s from file\n",
                      temphost->hostname, temphost->port, temphost->username);
        }
        else
        {
          GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                      "Error reading line `%s' in hostfile\n", buf);
          GNUNET_free (temphost);
          buf = &data[count + 1];
          continue;
        }
        /* temphost->hostname = buf; */
        temphost->next = hosts;
        hosts = temphost;
        buf = &data[count + 1];
      }
      else if ((data[count] == '\n') || (data[count] == '\0'))
        buf = &data[count + 1];
    }
  }

  peers_left = num_peers;
  pg = GNUNET_TESTING_daemons_start (cfg, peers_left,   /* Total number of peers */
                                     peers_left,        /* Number of outstanding connections */
                                     peers_left,        /* Number of parallel ssh connections, or peers being started at once */
                                     TIMEOUT, NULL, NULL, &my_cb, NULL, NULL,
                                     NULL, hosts);
  hostpos = hosts;
  while (hostpos != NULL)
  {
    temphost = hostpos->next;
    GNUNET_free (hostpos->hostname);
    GNUNET_free (hostpos->username);
    GNUNET_free (hostpos);
    hostpos = temphost;
  }
  GNUNET_free_non_null (data);
  GNUNET_assert (pg != NULL);

}
Esempio n. 27
0
/**
 * Start a peer with the given configuration
 * @param tth the testing handle
 * @param cfgname configuration file
 * @param peer_id a unique number to identify the peer
 * @param rec receive callback
 * @param nc connect callback
 * @param nd disconnect callback
 * @param start_cb start callback
 * @param cb_cls closure for callback
 * @return the peer context
 */
struct PeerContext *
GNUNET_TRANSPORT_TESTING_start_peer (struct GNUNET_TRANSPORT_TESTING_handle *tth,
                                     const char *cfgname, int peer_id,
                                     GNUNET_TRANSPORT_ReceiveCallback rec,
                                     GNUNET_TRANSPORT_NotifyConnect nc,
                                     GNUNET_TRANSPORT_NotifyDisconnect nd,
                                     GNUNET_TRANSPORT_TESTING_start_cb start_cb,
                                     void *cb_cls)
{
  char *emsg = NULL;
  struct GNUNET_PeerIdentity *dummy;

  GNUNET_assert (NULL != tth);
  GNUNET_assert (NULL != tth->tl_system);

  if (GNUNET_DISK_file_test (cfgname) == GNUNET_NO)
  {
    GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "transport-testing",
                     "File not found: `%s' \n", cfgname);
    return NULL;
  }

  struct PeerContext *p = GNUNET_new (struct PeerContext);
  GNUNET_CONTAINER_DLL_insert (tth->p_head, tth->p_tail, p);

  /* Create configuration and call testing lib to modify it */
  p->cfg = GNUNET_CONFIGURATION_create ();
  GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname));

  if (GNUNET_SYSERR == GNUNET_TESTING_configuration_create (tth->tl_system, p->cfg))
  {
    GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "transport-testing",
                     "Testing library failed to create unique configuration based on `%s'\n",
                     cfgname);
    GNUNET_free (p);
    return NULL;
  }

  p->no = peer_id;
  /* Configure peer with configuration */
  p->peer = GNUNET_TESTING_peer_configure (tth->tl_system, p->cfg, p->no, NULL, &emsg);
  if (NULL == p->peer)
  {
    GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "transport-testing",
                     "Testing library failed to create unique configuration based on `%s': `%s'\n",
                     cfgname, emsg);
    GNUNET_TRANSPORT_TESTING_stop_peer (tth, p);
    GNUNET_free_non_null (emsg);
    return NULL;
  }
  GNUNET_free_non_null (emsg);
  if (GNUNET_OK != GNUNET_TESTING_peer_start (p->peer))
  {
    GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "transport-testing",
                     "Testing library failed to create unique configuration based on `%s'\n",
                     cfgname);
    GNUNET_TRANSPORT_TESTING_stop_peer (tth, p);
    return NULL;
  }

  memset(&dummy, '\0', sizeof (dummy));
  GNUNET_TESTING_peer_get_identity (p->peer, &p->id);
  if (0 == memcmp (&dummy, &p->id, sizeof (struct GNUNET_PeerIdentity)))
  {
    GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "transport-testing",
                     "Testing library failed to obtain peer identity for peer %u\n",
                     p->no);
    GNUNET_TRANSPORT_TESTING_stop_peer (tth, p);
    return NULL;
  }
  else
  {
    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-testing",
                     "Peer %u configured with identity `%s'\n",
                     p->no,
                     GNUNET_i2s_full (&p->id));
  }

  p->tth = tth;
  p->nc = nc;
  p->nd = nd;
  p->rec = rec;
  p->start_cb = start_cb;
  if (cb_cls != NULL)
    p->cb_cls = cb_cls;
  else
    p->cb_cls = p;

  p->th = GNUNET_TRANSPORT_connect (p->cfg, NULL, p,
                                    &notify_receive,
                                    &notify_connect, &notify_disconnect);
  if (NULL == p->th)
  {
    GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "transport-testing",
                     "Failed to connect to transport service for peer  `%s': `%s'\n",
                     cfgname, emsg);
    GNUNET_TRANSPORT_TESTING_stop_peer (tth, p);
    return NULL;
  }

  p->ghh = GNUNET_TRANSPORT_get_hello (p->th, &get_hello, p);
  GNUNET_assert (p->ghh != NULL);

  return p;
}
Esempio n. 28
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;
}
/**
 * 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. 30
0
/**
 * Try to read the HELLOs in the given filename and discard expired
 * addresses.  Removes the file if one the HELLO is malformed.  If all
 * addresses are expired, the HELLO is also removed (but the HELLO
 * with the public key is still returned if it was found and valid).
 * The file can contain multiple HELLO messages.
 *
 * @param fn name of the file
 * @param unlink_garbage if #GNUNET_YES, try to remove useless files
 * @param r ReadHostFileContext to store the resutl
 */
static void
read_host_file (const char *fn,
                int unlink_garbage,
                struct ReadHostFileContext *r)
{
  char buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN;
  unsigned int size_total;
  struct GNUNET_TIME_Absolute now;
  unsigned int left;
  const struct GNUNET_HELLO_Message *hello;
  struct GNUNET_HELLO_Message *hello_clean;
  unsigned read_pos;
  int size_hello;

  r->friend_only_hello = NULL;
  r->hello = NULL;

  if (GNUNET_YES != GNUNET_DISK_file_test (fn))
    return;
  size_total = GNUNET_DISK_fn_read (fn, buffer, sizeof (buffer));
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Read %u bytes from `%s'\n",
              size_total,
              fn);
  if (size_total < sizeof (struct GNUNET_MessageHeader))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
		_("Failed to parse HELLO in file `%s': %s\n"),
		fn, "Fail has invalid size");
    if ( (GNUNET_YES == unlink_garbage) &&
	 (0 != UNLINK (fn)) &&
	 (ENOENT != errno) )
      GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
                                "unlink",
                                fn);
    return;
  }

  read_pos = 0;
  while (read_pos < size_total)
  {
    hello = (const struct GNUNET_HELLO_Message *) &buffer[read_pos];
    size_hello = GNUNET_HELLO_size (hello);
    if ( (0 == size_hello) ||
         (size_total - read_pos < size_hello) )
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                  _("Failed to parse HELLO in file `%s'\n"),
                  fn);
      if (0 == read_pos)
      {
        if ((GNUNET_YES == unlink_garbage) &&
            (0 != UNLINK (fn)) &&
            (ENOENT != errno) )
          GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
                                    "unlink",
                                    fn);
      }
      else
      {
        if ((GNUNET_YES == unlink_garbage) &&
            (0 != TRUNCATE (fn, read_pos)) &&
            (ENOENT != errno) )
          GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
                                    "truncate",
                                    fn);
      }
      return;
    }

    now = GNUNET_TIME_absolute_get ();
    hello_clean = GNUNET_HELLO_iterate_addresses (hello, GNUNET_YES,
						  &discard_expired, &now);
    if (NULL == hello_clean)
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                  _("Failed to parse HELLO in file `%s'\n"),
                  fn);
      if ((GNUNET_YES == unlink_garbage) &&
          (0 != UNLINK (fn)) &&
          (ENOENT != errno) )
        GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
                                  "unlink",
                                  fn);
      return;
    }
    left = 0;
    (void) GNUNET_HELLO_iterate_addresses (hello_clean, GNUNET_NO,
					   &count_addresses, &left);

    if (0 == left)
    {
      GNUNET_free (hello_clean);
      break;
    }

    if (GNUNET_NO == GNUNET_HELLO_is_friend_only (hello_clean))
    {
      if (NULL == r->hello)
	r->hello = hello_clean;
      else
      {
	GNUNET_break (0);
	GNUNET_free (r->hello);
	r->hello = hello_clean;
      }
    }
    else
    {
      if (NULL == r->friend_only_hello)
	r->friend_only_hello = hello_clean;
      else
      {
	GNUNET_break (0);
	GNUNET_free (r->friend_only_hello);
	r->friend_only_hello = hello_clean;
      }
    }
    read_pos += size_hello;
  }

  if (0 == left)
  {
    /* no addresses left, remove from disk */
    if ( (GNUNET_YES == unlink_garbage) &&
         (0 != UNLINK (fn)) )
      GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
                                "unlink",
                                fn);
  }
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
	      "Found `%s' and `%s' HELLO message in file\n",
	      (NULL != r->hello) ? "public" : "NON-public",
	      (NULL != r->friend_only_hello) ? "friend only" : "NO friend only");
}