static void
run_continuation (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct CpsRunContext *crc = cls;

  ok = (int) crc->phase;
  switch (crc->phase)
  {
  case RP_PUT:
#if VERBOSE
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Executing `%s' number %u\n", "PUT",
                crc->i);
#endif
    GNUNET_CRYPTO_hash (&crc->i, sizeof (int), &crc->key);
    GNUNET_DATASTORE_put (datastore, 0, &crc->key, get_size (crc->i),
                          get_data (crc->i), get_type (crc->i),
                          get_priority (crc->i), get_anonymity (crc->i), 0,
                          get_expiration (crc->i), 1, 1, TIMEOUT,
                          &check_success, crc);
    crc->i++;
    if (crc->i == ITERATIONS)
    {
      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                  "Sleeping to give datastore time to clean up\n");
      sleep (1);
      crc->phase = RP_GET;
      crc->i--;
    }
    break;
  case RP_GET:
#if VERBOSE
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Executing `%s' number %u\n", "GET",
                crc->i);
#endif
    GNUNET_CRYPTO_hash (&crc->i, sizeof (int), &crc->key);
    GNUNET_DATASTORE_get_key (datastore, crc->offset++, &crc->key,
                              get_type (crc->i), 1, 1, TIMEOUT, &check_value,
                              crc);
    break;
  case RP_GET_FAIL:
#if VERBOSE
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Executing `%s' number %u\n", "GET(f)",
                crc->i);
#endif
    GNUNET_CRYPTO_hash (&crc->i, sizeof (int), &crc->key);
    GNUNET_DATASTORE_get_key (datastore, crc->offset++, &crc->key,
                              get_type (crc->i), 1, 1, TIMEOUT, &check_nothing,
                              crc);
    break;
  case RP_DONE:
    GNUNET_assert (0 == crc->i);
#if VERBOSE
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Finished, disconnecting\n");
#endif
    GNUNET_DATASTORE_disconnect (datastore, GNUNET_YES);
    GNUNET_free (crc);
    ok = 0;
  }
}
Ejemplo n.º 2
0
/**
 * If necessary, connect to the datastore and remove the KBlocks.
 *
 * @param uc context for the unindex operation.
 */
void
GNUNET_FS_unindex_do_remove_kblocks_ (struct GNUNET_FS_UnindexContext *uc)
{
  const char *keyword;
  const struct GNUNET_CRYPTO_EcdsaPrivateKey *anon;
  struct GNUNET_CRYPTO_EcdsaPublicKey anon_pub;
  struct GNUNET_CRYPTO_EcdsaPublicKey dpub;

  if (NULL == uc->dsh)
    uc->dsh = GNUNET_DATASTORE_connect (uc->h->cfg);
  if (NULL == uc->dsh)
  {
    uc->state = UNINDEX_STATE_ERROR;
    uc->emsg = GNUNET_strdup (_("Failed to connect to `datastore' service."));
    GNUNET_FS_unindex_sync_ (uc);
    signal_unindex_error (uc);
    return;
  }
  if ( (NULL == uc->ksk_uri) ||
       (uc->ksk_offset >= uc->ksk_uri->data.ksk.keywordCount) )
  {
    unindex_finish (uc);
    return;
  }
  anon = GNUNET_CRYPTO_ecdsa_key_get_anonymous ();
  GNUNET_CRYPTO_ecdsa_key_get_public (anon,
                                      &anon_pub);
  keyword = &uc->ksk_uri->data.ksk.keywords[uc->ksk_offset][1];
  GNUNET_CRYPTO_ecdsa_public_key_derive (&anon_pub,
                                         keyword,
                                         "fs-ublock",
                                         &dpub);
  GNUNET_CRYPTO_hash (&dpub,
		      sizeof (dpub),
		      &uc->uquery);
  uc->dqe = GNUNET_DATASTORE_get_key (uc->dsh,
				      uc->roff++,
				      &uc->uquery,
				      GNUNET_BLOCK_TYPE_FS_UBLOCK,
				      0 /* priority */,
                                      1 /* queue size */,
				      GNUNET_TIME_UNIT_FOREVER_REL,
				      &process_kblock_for_unindex,
				      uc);
}
/**
 * Functions with this signature are called whenever a
 * complete query message is received.
 *
 * Do not call GNUNET_SERVER_mst_destroy in callback
 *
 * @param cls closure with the 'struct StreamClient'
 * @param client identification of the client, NULL
 * @param message the actual message
 * @return GNUNET_OK on success, GNUNET_SYSERR to stop further processing
 */
static int
request_cb (void *cls,
	    void *client,
	    const struct GNUNET_MessageHeader *message)
{
  struct StreamClient *sc = cls;
  const struct StreamQueryMessage *sqm;

  switch (ntohs (message->type))
  {
  case GNUNET_MESSAGE_TYPE_FS_STREAM_QUERY:
    if (sizeof (struct StreamQueryMessage) != 
	ntohs (message->size))
    {
      GNUNET_break_op (0);
      terminate_stream_async (sc);
      return GNUNET_SYSERR;
    }
    sqm = (const struct StreamQueryMessage *) message;
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
		"Received query for `%s' via stream\n",
		GNUNET_h2s (&sqm->query));
    GNUNET_STATISTICS_update (GSF_stats,
			      gettext_noop ("# queries received via stream"), 1,
			      GNUNET_NO);
    refresh_timeout_task (sc);
    sc->qe = GNUNET_DATASTORE_get_key (GSF_dsh,
				       0,
				       &sqm->query,
				       ntohl (sqm->type),
				       0 /* priority */, 
				       GSF_datastore_queue_size,
				       GNUNET_TIME_UNIT_FOREVER_REL,
				       &handle_datastore_reply, sc);
    if (NULL == sc->qe)
      continue_reading (sc);
    return GNUNET_OK;
  default:
    GNUNET_break_op (0);
    terminate_stream_async (sc);
    return GNUNET_SYSERR;
  }
}
Ejemplo n.º 4
0
/**
 * Function called from datastore with result from us looking for
 * a UBlock.  There are four cases:
 * 1) no result, means we move on to the next keyword
 * 2) UID is the same as the first UID, means we move on to next keyword
 * 3) UBlock for a different CHK, means we keep looking for more
 * 4) UBlock is for our CHK, means we remove the block and then move
 *           on to the next keyword
 *
 * @param cls the 'struct GNUNET_FS_UnindexContext *'
 * @param key key for the content
 * @param size number of bytes in data
 * @param data content stored
 * @param type type of the content
 * @param priority priority of the content
 * @param anonymity anonymity-level for the content
 * @param expiration expiration time for the content
 * @param uid unique identifier for the datum;
 *        maybe 0 if no unique identifier is available
 */
static void
process_kblock_for_unindex (void *cls,
			    const struct GNUNET_HashCode *key,
			    size_t size,
                            const void *data,
			    enum GNUNET_BLOCK_Type type,
			    uint32_t priority,
			    uint32_t anonymity,
			    struct GNUNET_TIME_Absolute expiration,
                            uint64_t uid)
{
  struct GNUNET_FS_UnindexContext *uc = cls;
  const struct UBlock *ub;
  struct GNUNET_FS_Uri *chk_uri;
  struct GNUNET_HashCode query;
  struct GNUNET_HashCode dh;

  uc->dqe = NULL;
  if (NULL == data)
  {
    /* no result */
    GNUNET_CONTAINER_multihashmap_clear (uc->seen_dh);
    uc->ksk_offset++;
    GNUNET_FS_unindex_do_remove_kblocks_ (uc);
    return;
  }
  GNUNET_CRYPTO_hash (data,
                      size,
                      &dh);
  if (GNUNET_YES ==
      GNUNET_CONTAINER_multihashmap_contains (uc->seen_dh,
                                              &dh))
  {
    GNUNET_CONTAINER_multihashmap_clear (uc->seen_dh);
    uc->ksk_offset++;
    GNUNET_FS_unindex_do_remove_kblocks_ (uc);
    return;
  }
  GNUNET_assert (GNUNET_OK ==
                 GNUNET_CONTAINER_multihashmap_put (uc->seen_dh,
                                                    &dh,
                                                    uc,
                                                    GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
  GNUNET_assert (GNUNET_BLOCK_TYPE_FS_UBLOCK == type);
  if (size < sizeof (struct UBlock))
  {
    GNUNET_break (0);
    goto get_next;
  }
  ub = data;
  GNUNET_CRYPTO_hash (&ub->verification_key,
		      sizeof (ub->verification_key),
		      &query);
  if (0 != memcmp (&query,
                   key,
                   sizeof (struct GNUNET_HashCode)))
  {
    /* result does not match our keyword, skip */
    goto get_next;
  }
  {
    char pt[size - sizeof (struct UBlock)];
    struct GNUNET_CRYPTO_EcdsaPublicKey anon_pub;
    const char *keyword;

    GNUNET_CRYPTO_ecdsa_key_get_public (GNUNET_CRYPTO_ecdsa_key_get_anonymous (),
                                        &anon_pub);
    keyword = &uc->ksk_uri->data.ksk.keywords[uc->ksk_offset][1];
    GNUNET_FS_ublock_decrypt_ (&ub[1], size - sizeof (struct UBlock),
			       &anon_pub,
			       keyword,
			       pt);
    if (NULL == memchr (&pt[1], 0, sizeof (pt) - 1))
    {
      GNUNET_break_op (0); /* malformed UBlock */
      goto get_next;
    }
    chk_uri = GNUNET_FS_uri_parse (&pt[1], NULL);
    if (NULL == chk_uri)
    {
      GNUNET_break_op (0); /* malformed UBlock */
      goto get_next;
    }
  }
  if (0 != memcmp (&uc->chk,
		   &chk_uri->data.chk.chk,
		   sizeof (struct ContentHashKey)))
  {
    /* different CHK, ignore */
    GNUNET_FS_uri_destroy (chk_uri);
    goto get_next;
  }
  GNUNET_FS_uri_destroy (chk_uri);
  /* matches! */
  uc->dqe = GNUNET_DATASTORE_remove (uc->dsh,
				     key,
                                     size,
                                     data,
				     0 /* priority */,
                                     1 /* queue size */,
				     GNUNET_TIME_UNIT_FOREVER_REL,
				     &continue_after_remove,
				     uc);
  return;
 get_next:
  uc->dqe = GNUNET_DATASTORE_get_key (uc->dsh,
				      uc->roff++,
				      &uc->uquery,
				      GNUNET_BLOCK_TYPE_FS_UBLOCK,
				      0 /* priority */,
                                      1 /* queue size */,
				      GNUNET_TIME_UNIT_FOREVER_REL,
				      &process_kblock_for_unindex,
				      uc);
}