/**
 * Create an entry for a file in a publish-structure.
 *
 * @param h handle to the file sharing subsystem
 * @param client_info initial value for the client-info value for this entry
 * @param length length of the file
 * @param reader function that can be used to obtain the data for the file
 * @param reader_cls closure for "reader"
 * @param keywords under which keywords should this file be available
 *         directly; can be NULL
 * @param meta metadata for the file
 * @param do_index GNUNET_YES for index, GNUNET_NO for insertion,
 *                GNUNET_SYSERR for simulation
 * @param bo block options
 * @return publish structure entry for the file
 */
struct GNUNET_FS_FileInformation *
GNUNET_FS_file_information_create_from_reader (struct GNUNET_FS_Handle *h,
                                               void *client_info,
                                               uint64_t length,
                                               GNUNET_FS_DataReader reader,
                                               void *reader_cls,
                                               const struct GNUNET_FS_Uri
                                               *keywords,
                                               const struct
                                               GNUNET_CONTAINER_MetaData *meta,
                                               int do_index,
                                               const struct
                                               GNUNET_FS_BlockOptions *bo)
{
  struct GNUNET_FS_FileInformation *ret;

  if ((GNUNET_YES == do_index) && (reader != &GNUNET_FS_data_reader_file_))
  {
    GNUNET_break (0);
    return NULL;
  }
  ret = GNUNET_malloc (sizeof (struct GNUNET_FS_FileInformation));
  ret->h = h;
  ret->client_info = client_info;
  ret->meta = GNUNET_CONTAINER_meta_data_duplicate (meta);
  if (ret->meta == NULL)
    ret->meta = GNUNET_CONTAINER_meta_data_create ();
  ret->keywords = (keywords == NULL) ? NULL : GNUNET_FS_uri_dup (keywords);
  ret->data.file.reader = reader;
  ret->data.file.reader_cls = reader_cls;
  ret->data.file.do_index = do_index;
  ret->data.file.file_size = length;
  ret->bo = *bo;
  return ret;
}
/**
 * Create an entry for an empty directory in a publish-structure.
 * This function should be used by applications for which the
 * use of "GNUNET_FS_file_information_create_from_directory"
 * is not appropriate.
 *
 * @param h handle to the file sharing subsystem
 * @param client_info initial value for the client-info value for this entry
 * @param meta metadata for the directory
 * @param keywords under which keywords should this directory be available
 *         directly; can be NULL
 * @param bo block options
 * @param filename name of the directory; can be NULL
 * @return publish structure entry for the directory , NULL on error
 */
struct GNUNET_FS_FileInformation *
GNUNET_FS_file_information_create_empty_directory (struct GNUNET_FS_Handle *h,
                                                   void *client_info,
                                                   const struct GNUNET_FS_Uri
                                                   *keywords,
                                                   const struct
                                                   GNUNET_CONTAINER_MetaData
                                                   *meta,
                                                   const struct
                                                   GNUNET_FS_BlockOptions *bo,
                                                   const char *filename)
{
  struct GNUNET_FS_FileInformation *ret;

  ret = GNUNET_malloc (sizeof (struct GNUNET_FS_FileInformation));
  ret->h = h;
  ret->client_info = client_info;
  ret->meta = GNUNET_CONTAINER_meta_data_duplicate (meta);
  ret->keywords = GNUNET_FS_uri_dup (keywords);
  ret->bo = *bo;
  ret->is_directory = GNUNET_YES;
  if (filename != NULL)
    ret->filename = GNUNET_strdup (filename);
  return ret;
}
Example #3
0
static void
sks_cont (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg)
{
  struct GNUNET_CONTAINER_MetaData *meta;
  struct GNUNET_FS_Uri *ksk_uri;
  char *msg;
  struct GNUNET_FS_BlockOptions bo;

  if (NULL == uri)
  {
    fprintf (stderr, "Error publishing: %s\n", emsg);
    err = 1;
    GNUNET_FS_stop (fs);
    return;
  }
  meta = GNUNET_CONTAINER_meta_data_create ();
  msg = NULL;
  ksk_uri = GNUNET_FS_uri_parse ("gnunet://fs/ksk/ns-search", &msg);
  GNUNET_assert (NULL == msg);
  ksk_expect_uri = GNUNET_FS_uri_dup (uri);
  bo.content_priority = 1;
  bo.anonymity_level = 1;
  bo.replication_level = 0;
  bo.expiration_time =
      GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES);
  GNUNET_FS_publish_ksk (fs, ksk_uri, meta, uri, &bo,
                         GNUNET_FS_PUBLISH_OPTION_NONE, &publish_cont, NULL);
  GNUNET_FS_uri_destroy (ksk_uri);
  GNUNET_CONTAINER_meta_data_destroy (meta);
}
Example #4
0
static void
adv_cont (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg)
{
  struct GNUNET_CONTAINER_MetaData *meta;
  struct GNUNET_CRYPTO_EcdsaPrivateKey *ns;
  struct GNUNET_FS_BlockOptions bo;

  if (NULL != emsg)
  {
    FPRINTF (stderr, "Error publishing: %s\n", emsg);
    err = 1;
    GNUNET_FS_stop (fs);
    return;
  }
  ns = GNUNET_CRYPTO_ecdsa_key_create ();
  meta = GNUNET_CONTAINER_meta_data_create ();
  sks_expect_uri = GNUNET_FS_uri_dup (uri);
  bo.content_priority = 1;
  bo.anonymity_level = 1;
  bo.replication_level = 0;
  bo.expiration_time =
      GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES);
  GNUNET_CRYPTO_ecdsa_key_get_public (ns, &nsid);
  GNUNET_FS_publish_sks (fs, ns, "this", "next", meta, uri,
                         &bo, GNUNET_FS_PUBLISH_OPTION_NONE, &sks_cont, NULL);
  GNUNET_CONTAINER_meta_data_destroy (meta);
  GNUNET_free (ns);
}
static void
do_wait (void *cls,
         const struct GNUNET_FS_Uri *uri,
	 const char *fn)
{
  struct DownloadContext *dc;

  if (NULL == uri)
  {
    GNUNET_SCHEDULER_shutdown ();
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "Timeout during upload attempt, shutting down with error\n");
    ok = 1;
    return;
  }
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Waiting to allow content to migrate\n");
  dc = GNUNET_new (struct DownloadContext);
  dc->uri = GNUNET_FS_uri_dup (uri);
  if (NULL != fn)
    dc->fn = GNUNET_strdup (fn);
  (void) GNUNET_SCHEDULER_add_delayed (MIGRATION_DELAY,
				       &stop_source_peer,
				       dc);
}
static void
do_publish2 (void *cls,
	     const struct GNUNET_FS_Uri *u1,
	     const char *fn)
{
  int do_index;
  int anonymity;

  if (NULL == u1)
  {
    cleanup ();
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                "Timeout during upload attempt, shutting down with error\n");
    ok = 1;
    return;
  }
  if (NULL != fn)
    fn1 = GNUNET_strdup (fn);
  uri1 = GNUNET_FS_uri_dup (u1);
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Publishing %llu bytes\n",
              (unsigned long long) FILESIZE);
  if (NULL != strstr (progname, "index"))
    do_index = GNUNET_YES;
  else
    do_index = GNUNET_NO;
  if (NULL != strstr (progname, "dht"))
    anonymity = 0;
  else
    anonymity = 1;

  GNUNET_FS_TEST_publish (daemons[NUM_DAEMONS - 2], TIMEOUT, anonymity,
                          do_index, FILESIZE, SEED2, VERBOSE, &do_downloads,
                          NULL);
}
Example #7
0
/**
 * Start download probes for the given search result.
 *
 * @param h file-sharing handle to use for the operation
 * @param uri URI to probe
 * @param meta meta data associated with the URI
 * @param client_info client info pointer to use for associated events
 * @param anonymity anonymity level to use for the probes
 * @return the search result handle to access the probe activity
 */
struct GNUNET_FS_SearchResult *
GNUNET_FS_probe (struct GNUNET_FS_Handle *h,
		 const struct GNUNET_FS_Uri *uri,
		 const struct GNUNET_CONTAINER_MetaData *meta,
		 void *client_info,
		 uint32_t anonymity)
{
  struct GNUNET_FS_SearchResult *sr;

  GNUNET_assert (NULL != h);
  sr = GNUNET_new (struct GNUNET_FS_SearchResult);
  sr->h = h;
  sr->uri = GNUNET_FS_uri_dup (uri);
  sr->meta = GNUNET_CONTAINER_meta_data_duplicate (meta);
  sr->client_info = client_info;
  sr->anonymity = anonymity;
  GNUNET_FS_search_start_probe_ (sr);
  return sr;
}
Example #8
0
/**
 * Function called by the directory scanner as we extract keywords
 * that we will need to remove UBlocks.
 *
 * @param cls the 'struct GNUNET_FS_UnindexContext *'
 * @param filename which file we are making progress on
 * @param is_directory #GNUNET_YES if this is a directory,
 *                     #GNUNET_NO if this is a file
 *                     #GNUNET_SYSERR if it is neither (or unknown)
 * @param reason kind of progress we are making
 */
static void
unindex_directory_scan_cb (void *cls,
			   const char *filename,
			   int is_directory,
			   enum GNUNET_FS_DirScannerProgressUpdateReason reason)
{
  struct GNUNET_FS_UnindexContext *uc = cls;
  static struct GNUNET_FS_ShareTreeItem * directory_scan_result;

  switch (reason)
  {
  case GNUNET_FS_DIRSCANNER_FINISHED:
    directory_scan_result = GNUNET_FS_directory_scan_get_result (uc->dscan);
    uc->dscan = NULL;
    if (NULL != directory_scan_result->ksk_uri)
    {
      uc->ksk_uri = GNUNET_FS_uri_dup (directory_scan_result->ksk_uri);
      uc->state = UNINDEX_STATE_DS_REMOVE_KBLOCKS;
      GNUNET_FS_unindex_sync_ (uc);
      GNUNET_FS_unindex_do_remove_kblocks_ (uc);
    }
    else
    {
      uc->emsg = GNUNET_strdup (_("Failed to get KSKs from directory scan."));
      GNUNET_FS_unindex_sync_ (uc);
      unindex_finish (uc);
    }
    GNUNET_FS_share_tree_free (directory_scan_result);
    break;
  case GNUNET_FS_DIRSCANNER_INTERNAL_ERROR:
    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
		_("Internal error scanning `%s'.\n"),
		uc->filename);
    GNUNET_FS_directory_scan_abort (uc->dscan);
    uc->dscan = NULL;
    uc->emsg = GNUNET_strdup (_("Failed to get KSKs from directory scan."));
    GNUNET_FS_unindex_sync_ (uc);
    unindex_finish (uc);
    break;
  default:
    break;
  }
}
Example #9
0
/**
 * We have received a KSK result.  Check how it fits in with the
 * overall query and notify the client accordingly.
 *
 * @param sc context for the overall query
 * @param ent entry for the specific keyword
 * @param uri the URI that was found
 * @param meta metadata associated with the URI
 *        under the @a ent keyword
 */
static void
process_ksk_result (struct GNUNET_FS_SearchContext *sc,
                    struct SearchRequestEntry *ent,
                    const struct GNUNET_FS_Uri *uri,
                    const struct GNUNET_CONTAINER_MetaData *meta)
{
  struct GNUNET_HashCode key;
  struct GNUNET_FS_SearchResult *sr;
  struct GetResultContext grc;
  int is_new;
  unsigned int koff;

  /* check if new */
  GNUNET_assert (NULL != sc);
  GNUNET_FS_uri_to_key (uri, &key);
  if (GNUNET_SYSERR ==
      GNUNET_CONTAINER_multihashmap_get_multiple (ent->results, &key,
                                                  &test_result_present,
                                                  (void *) uri))
    return;                     /* duplicate result */
  /* try to find search result in master map */
  grc.sr = NULL;
  grc.uri = uri;
  GNUNET_CONTAINER_multihashmap_get_multiple (sc->master_result_map, &key,
                                              &get_result_present, &grc);
  sr = grc.sr;
  is_new = (NULL == sr) || (sr->mandatory_missing > 0);
  if (NULL == sr)
  {
    sr = GNUNET_new (struct GNUNET_FS_SearchResult);
    sr->h = sc->h;
    sr->sc = sc;
    sr->anonymity = sc->anonymity;
    sr->uri = GNUNET_FS_uri_dup (uri);
    sr->meta = GNUNET_CONTAINER_meta_data_duplicate (meta);
    sr->mandatory_missing = sc->mandatory_count;
    sr->key = key;
    sr->keyword_bitmap = GNUNET_malloc ((sc->uri->data.ksk.keywordCount + 7) / 8); /* round up, count bits */
    GNUNET_CONTAINER_multihashmap_put (sc->master_result_map, &key, sr,
                                       GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
  }
static void
do_downloads (void *cls, const struct GNUNET_FS_Uri *u2,
	      const char *fn)
{
  int anonymity;
  unsigned int i;

  if (NULL == u2)
  {
    cleanup ();
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                "Timeout during upload attempt, shutting down with error\n");
    ok = 1;
    return;
  }
  if (NULL != fn)
    fn2 = GNUNET_strdup (fn);
  uri2 = GNUNET_FS_uri_dup (u2);
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Downloading %llu bytes\n",
              (unsigned long long) FILESIZE);
  start_time = GNUNET_TIME_absolute_get ();
  if (NULL != strstr (progname, "dht"))
    anonymity = 0;
  else
    anonymity = 1;
  /* (semi) leach-download(s); not true leaches since
   * these peers do participate in sharing, they just
   * don't have to offer anything *initially*.  */
  for (i = 0; i < NUM_DAEMONS - 2; i++)
    GNUNET_FS_TEST_download (daemons[i], TIMEOUT, anonymity,
                             0 == (i % 2) ? SEED1 : SEED2,
                             0 == (i % 2) ? uri1 : uri2, VERBOSE, &do_report,
                             "leach");
  /* mutual downloads of (primary) sharing peers */
  GNUNET_FS_TEST_download (daemons[NUM_DAEMONS - 2], TIMEOUT, anonymity, SEED1,
                           uri1, VERBOSE, &do_report, "seeder 2");
  GNUNET_FS_TEST_download (daemons[NUM_DAEMONS - 1], TIMEOUT, anonymity, SEED2,
                           uri2, VERBOSE, &do_report, "seeder 1");
}
Example #11
0
/**
 * Publish a CHK under various keywords on GNUnet.
 *
 * @param h handle to the file sharing subsystem
 * @param ksk_uri keywords to use
 * @param meta metadata to use
 * @param uri URI to refer to in the KBlock
 * @param bo per-block options
 * @param options publication options
 * @param cont continuation
 * @param cont_cls closure for cont
 * @return NULL on error ('cont' will still be called)
 */
struct GNUNET_FS_PublishKskContext *
GNUNET_FS_publish_ksk (struct GNUNET_FS_Handle *h,
                       const struct GNUNET_FS_Uri *ksk_uri,
                       const struct GNUNET_CONTAINER_MetaData *meta,
                       const struct GNUNET_FS_Uri *uri,
                       const struct GNUNET_FS_BlockOptions *bo,
                       enum GNUNET_FS_PublishOptions options,
                       GNUNET_FS_PublishContinuation cont, void *cont_cls)
{
  struct GNUNET_FS_PublishKskContext *pkc;
  char *uris;
  size_t size;
  char *kbe;
  char *sptr;

  GNUNET_assert (NULL != uri);
  pkc = GNUNET_malloc (sizeof (struct GNUNET_FS_PublishKskContext));
  pkc->h = h;
  pkc->bo = *bo;
  pkc->cont = cont;
  pkc->cont_cls = cont_cls;
  if (0 == (options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY))
  {
    pkc->dsh = GNUNET_DATASTORE_connect (h->cfg);
    if (NULL == pkc->dsh)
    {
      cont (cont_cls, NULL, _("Could not connect to datastore."));
      GNUNET_free (pkc);
      return NULL;
    }
  }
  if (meta == NULL)
    pkc->mdsize = 0;
  else
    pkc->mdsize = GNUNET_CONTAINER_meta_data_get_serialized_size (meta);
  GNUNET_assert (pkc->mdsize >= 0);
  uris = GNUNET_FS_uri_to_string (uri);
  pkc->slen = strlen (uris) + 1;
  size = pkc->mdsize + sizeof (struct KBlock) + pkc->slen;
  if (size > MAX_KBLOCK_SIZE)
  {
    size = MAX_KBLOCK_SIZE;
    pkc->mdsize = size - sizeof (struct KBlock) - pkc->slen;
  }
  pkc->kb = GNUNET_malloc (size);
  kbe = (char *) &pkc->kb[1];
  memcpy (kbe, uris, pkc->slen);
  GNUNET_free (uris);
  sptr = &kbe[pkc->slen];
  if (meta != NULL)
    pkc->mdsize =
        GNUNET_CONTAINER_meta_data_serialize (meta, &sptr, pkc->mdsize,
                                              GNUNET_CONTAINER_META_DATA_SERIALIZE_PART);
  if (-1 == pkc->mdsize)
  {
    GNUNET_break (0);
    GNUNET_free (pkc->kb);
    if (pkc->dsh != NULL)
    {
      GNUNET_DATASTORE_disconnect (pkc->dsh, GNUNET_NO);
      pkc->dsh = NULL;
    }
    GNUNET_free (pkc);
    cont (cont_cls, NULL, _("Internal error."));
    return NULL;
  }
  size = sizeof (struct KBlock) + pkc->slen + pkc->mdsize;

  pkc->cpy = GNUNET_malloc (size);
  pkc->cpy->purpose.size =
      htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
             sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) +
             pkc->mdsize + pkc->slen);
  pkc->cpy->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_FS_KBLOCK);
  pkc->ksk_uri = GNUNET_FS_uri_dup (ksk_uri);
  pkc->ksk_task = GNUNET_SCHEDULER_add_now (&publish_ksk_cont, pkc);
  return pkc;
}
Example #12
0
/**
 * Process a share item tree, moving frequent keywords up and
 * copying frequent metadata up.
 *
 * @param tc trim context with hash maps to use
 * @param tree tree to trim
 */
static void
share_tree_trim (struct TrimContext *tc,
		 struct GNUNET_FS_ShareTreeItem *tree)
{
  struct GNUNET_FS_ShareTreeItem *pos;
  unsigned int num_children;

  /* first, trim all children */
  num_children = 0;
  for (pos = tree->children_head; NULL != pos; pos = pos->next)
  {
    share_tree_trim (tc, pos);
    num_children++;
  }

  /* consider adding filename to directory meta data */
  if (tree->is_directory == GNUNET_YES)
  {
    const char *user = getenv ("USER");
    if ( (user == NULL) || 
	 (0 != strncasecmp (user, tree->short_filename, strlen(user))))
    {
      /* only use filename if it doesn't match $USER */
      if (NULL == tree->meta)
	tree->meta = GNUNET_CONTAINER_meta_data_create ();
      GNUNET_CONTAINER_meta_data_insert (tree->meta, "<libgnunetfs>",
					 EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME,
					 EXTRACTOR_METAFORMAT_UTF8,
					 "text/plain", tree->short_filename,
					 strlen (tree->short_filename) + 1);
    }
  }

  if (1 >= num_children)
    return; /* nothing to trim */
  
  /* now, count keywords and meta data in children */
  for (pos = tree->children_head; NULL != pos; pos = pos->next)
  {
    if (NULL != pos->meta)
      GNUNET_CONTAINER_meta_data_iterate (pos->meta, &add_to_meta_counter, tc->metacounter);    
    if (NULL != pos->ksk_uri)
      GNUNET_FS_uri_ksk_get_keywords (pos->ksk_uri, &add_to_keyword_counter, tc->keywordcounter);
  }

  /* calculate threshold for moving keywords / meta data */
  tc->move_threshold = 1 + (num_children / 2);

  /* remove high-frequency keywords from children */
  for (pos = tree->children_head; NULL != pos; pos = pos->next)
  {
    tc->pos = pos;
    if (NULL != pos->ksk_uri)
    {
      struct GNUNET_FS_Uri *ksk_uri_copy = GNUNET_FS_uri_dup (pos->ksk_uri);
      GNUNET_FS_uri_ksk_get_keywords (ksk_uri_copy, &remove_high_frequency_keywords, tc);
      GNUNET_FS_uri_destroy (ksk_uri_copy);
    }
  }

  /* add high-frequency meta data and keywords to parent */
  tc->pos = tree;
  GNUNET_CONTAINER_multihashmap_iterate (tc->keywordcounter, 
					 &migrate_and_drop_keywords,
					 tc);
  GNUNET_CONTAINER_multihashmap_iterate (tc->metacounter, 
					 &migrate_and_drop_metadata,
					 tc);
}