static void
key_iterator (void *cls, const struct GNUNET_HashCode *key,
	      const char *proof,
              int accepting, unsigned int num_edges,
              const struct REGEX_BLOCK_Edge *edges)
{
  unsigned int i;
  struct IteratorContext *ctx = cls;
  char *out_str;
  char *state_id = GNUNET_strdup (GNUNET_h2s (key));

  GNUNET_assert (NULL != proof);
  if (GNUNET_YES == ctx->should_save_graph)
  {
    if (GNUNET_YES == accepting)
      GNUNET_asprintf (&out_str, "\"%s\" [shape=doublecircle]\n", state_id);
    else
      GNUNET_asprintf (&out_str, "\"%s\" [shape=circle]\n", state_id);
    fwrite (out_str, strlen (out_str), 1, ctx->graph_filep);
    GNUNET_free (out_str);

    for (i = 0; i < num_edges; i++)
    {
      transition_counter++;
      GNUNET_asprintf (&out_str, "\"%s\" -> \"%s\" [label = \"%s (%s)\"]\n",
                       state_id, GNUNET_h2s (&edges[i].destination),
                       edges[i].label, proof);
      fwrite (out_str, strlen (out_str), 1, ctx->graph_filep);

      GNUNET_free (out_str);
    }
  }
  else
  {
    for (i = 0; i < num_edges; i++)
      transition_counter++;
  }

  for (i = 0; i < ctx->string_count; i++)
  {
    if (0 == strcmp (proof, ctx->strings[i]))
      ctx->match_count++;
  }

  if (GNUNET_OK != REGEX_BLOCK_check_proof (proof, strlen (proof), key))
  {
    ctx->error++;
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                "Proof check failed: proof: %s key: %s\n", proof, state_id);
  }
  GNUNET_free (state_id);
}
Example #2
0
/**
 * Process a given reply that might match the given
 * request.
 *
 * @param cls the 'struct GNUNET_DHT_ClientResultMessage'
 * @param key query of the request
 * @param value the 'struct GNUNET_DHT_RouteHandle' of a request matching the same key
 * @return GNUNET_YES to continue to iterate over all results,
 *         GNUNET_NO if the reply is malformed
 */
static int
process_reply (void *cls, const GNUNET_HashCode * key, void *value)
{
  const struct GNUNET_DHT_ClientResultMessage *dht_msg = cls;
  struct GNUNET_DHT_GetHandle *get_handle = value;
  const struct GNUNET_PeerIdentity *put_path;
  const struct GNUNET_PeerIdentity *get_path;
  uint32_t put_path_length;
  uint32_t get_path_length;
  size_t data_length;
  size_t msize;
  size_t meta_length;
  const void *data;

  if (dht_msg->unique_id != get_handle->unique_id)
  {
    /* UID mismatch */
    LOG (GNUNET_ERROR_TYPE_DEBUG,
         "Ignoring reply for %s: UID mismatch: %llu/%llu\n", GNUNET_h2s (key),
         dht_msg->unique_id, get_handle->unique_id);
    return GNUNET_YES;
  }
  msize = ntohs (dht_msg->header.size);
  put_path_length = ntohl (dht_msg->put_path_length);
  get_path_length = ntohl (dht_msg->get_path_length);
  meta_length =
      sizeof (struct GNUNET_DHT_ClientResultMessage) +
      sizeof (struct GNUNET_PeerIdentity) * (get_path_length + put_path_length);
  if ((msize < meta_length) ||
      (get_path_length >
       GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)) ||
      (put_path_length >
       GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
  {
    GNUNET_break (0);
    return GNUNET_NO;
  }
  data_length = msize - meta_length;
  LOG (GNUNET_ERROR_TYPE_DEBUG, "Giving %u byte reply for %s to application\n",
       (unsigned int) data_length, GNUNET_h2s (key));
  put_path = (const struct GNUNET_PeerIdentity *) &dht_msg[1];
  get_path = &put_path[put_path_length];
  data = &get_path[get_path_length];
  get_handle->iter (get_handle->iter_cls,
                    GNUNET_TIME_absolute_ntoh (dht_msg->expiration), key,
                    get_path, get_path_length, put_path, put_path_length,
                    ntohl (dht_msg->type), data_length, data);
  return GNUNET_YES;
}
Example #3
0
/**
 * Get a result for a particular key from the datastore.  The processor
 * will only be called once.
 *
 * @param h handle to the datastore
 * @param offset offset of the result (modulo num-results); set to
 *               a random 64-bit value initially; then increment by
 *               one each time; detect that all results have been found by uid
 *               being again the first uid ever returned.
 * @param key maybe NULL (to match all entries)
 * @param type desired type, 0 for any
 * @param queue_priority ranking of this request in the priority queue
 * @param max_queue_size at what queue size should this request be dropped
 *        (if other requests of higher priority are in the queue)
 * @param timeout how long to wait at most for a response
 * @param proc function to call on each matching value;
 *        will be called once with a NULL value at the end
 * @param proc_cls closure for proc
 * @return NULL if the entry was not queued, otherwise a handle that can be used to
 *         cancel
 */
struct GNUNET_DATASTORE_QueueEntry *
GNUNET_DATASTORE_get_key (struct GNUNET_DATASTORE_Handle *h, uint64_t offset,
                          const struct GNUNET_HashCode * key,
                          enum GNUNET_BLOCK_Type type,
                          unsigned int queue_priority,
                          unsigned int max_queue_size,
                          struct GNUNET_TIME_Relative timeout,
                          GNUNET_DATASTORE_DatumProcessor proc, void *proc_cls)
{
  struct GNUNET_DATASTORE_QueueEntry *qe;
  struct GetMessage *gm;
  union QueueContext qc;

  GNUNET_assert (NULL != proc);
  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Asked to look for data of type %u under key `%s'\n",
       (unsigned int) type, GNUNET_h2s (key));
  qc.rc.proc = proc;
  qc.rc.proc_cls = proc_cls;
  qe = make_queue_entry (h, sizeof (struct GetMessage), queue_priority,
                         max_queue_size, timeout, &process_result_message, &qc);
  if (qe == NULL)
  {
    LOG (GNUNET_ERROR_TYPE_DEBUG, "Could not queue request for `%s'\n",
         GNUNET_h2s (key));
    return NULL;
  }
#if INSANE_STATISTICS
  GNUNET_STATISTICS_update (h->stats, gettext_noop ("# GET requests executed"),
                            1, GNUNET_NO);
#endif
  gm = (struct GetMessage *) &qe[1];
  gm->header.type = htons (GNUNET_MESSAGE_TYPE_DATASTORE_GET);
  gm->type = htonl (type);
  gm->offset = GNUNET_htonll (offset);
  if (key != NULL)
  {
    gm->header.size = htons (sizeof (struct GetMessage));
    gm->key = *key;
  }
  else
  {
    gm->header.size =
        htons (sizeof (struct GetMessage) - sizeof (struct GNUNET_HashCode));
  }
  process_queue (h);
  return qe;
}
Example #4
0
/**
 * Store content in DHT.
 *
 * @param cls closure
 * @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_dht_put_content (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 PutOperator *po = cls;

  po->dht_qe = NULL;
  if (key == NULL)
  {
    po->zero_anonymity_count_estimate = po->current_offset - 1;
    po->current_offset = 0;
    po->dht_task = GNUNET_SCHEDULER_add_now (&delay_dht_put_task, po);
    return;
  }
  po->zero_anonymity_count_estimate =
      GNUNET_MAX (po->current_offset, po->zero_anonymity_count_estimate);
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Retrieved block `%s' of type %u for DHT PUT\n", GNUNET_h2s (key),
              type);
  po->dht_put = GNUNET_DHT_put (GSF_dht, key, DEFAULT_PUT_REPLICATION,
				GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, type, size, data,
				expiration, GNUNET_TIME_UNIT_FOREVER_REL,
				&delay_dht_put_blocks, po);
}
Example #5
0
/**
 * Handler for port close requests.
 *
 * @param cls Identification of the client.
 * @param pmsg The actual message.
 */
static void
handle_port_close (void *cls,
                   const struct GNUNET_CADET_PortMessage *pmsg)
{
  struct CadetClient *c = cls;

  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Open port %s requested by client %u\n",
       GNUNET_h2s (&pmsg->port),
       c->id);
  if (GNUNET_YES !=
      GNUNET_CONTAINER_multihashmap_remove (c->ports,
                                            &pmsg->port,
                                            c))
  {
    GNUNET_break (0);
    GNUNET_SERVICE_client_drop (c->client);
    return;
  }
  GNUNET_assert (GNUNET_YES ==
                 GNUNET_CONTAINER_multihashmap_remove (open_ports,
                                                       &pmsg->port,
                                                       c));

  GNUNET_SERVICE_client_continue (c->client);
}
/**
 * We've paired up a client session with an incoming CADET request.
 * Initiate set intersection work.
 *
 * @param s client session to start intersection for
 */
static void
start_intersection (struct BobServiceSession *s)
{
  struct GNUNET_HashCode set_sid;

  GNUNET_CRYPTO_hash (&s->session_id,
                      sizeof (struct GNUNET_HashCode),
                      &set_sid);
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Got session with key %s and %u elements, starting intersection.\n",
              GNUNET_h2s (&s->session_id),
              (unsigned int) s->total);

  s->intersection_op
    = GNUNET_SET_prepare (&s->cadet->peer,
                          &set_sid,
                          NULL,
                          GNUNET_SET_RESULT_REMOVED,
                          &cb_intersection_element_removed,
                          s);
  if (GNUNET_OK !=
      GNUNET_SET_commit (s->intersection_op,
                         s->intersection_set))
  {
    GNUNET_break (0);
    s->status = GNUNET_SCALARPRODUCT_STATUS_FAILURE;
    prepare_client_end_notification (s);
    return;
  }
  GNUNET_SET_destroy (s->intersection_set);
  s->intersection_set = NULL;
}
/**
 * Function called whenever a channel is destroyed.  Should clean up
 * any associated state.
 *
 * It must NOT call #GNUNET_CADET_channel_destroy() on the channel.
 *
 * @param cls closure (set from #GNUNET_CADET_connect())
 * @param channel connection to the other end (henceforth invalid)
 * @param channel_ctx place where local state associated
 *                   with the channel is stored
 */
static void
cb_channel_destruction (void *cls,
                        const struct GNUNET_CADET_Channel *channel,
                        void *channel_ctx)
{
  struct CadetIncomingSession *in = channel_ctx;
  struct BobServiceSession *s;

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Peer disconnected, terminating session %s with peer %s\n",
              GNUNET_h2s (&in->session_id),
              GNUNET_i2s (&in->peer));
  if (NULL != in->cadet_mq)
  {
    GNUNET_MQ_destroy (in->cadet_mq);
    in->cadet_mq = NULL;
  }
  in->channel = NULL;
  if (NULL != (s = in->s))
  {
    if (GNUNET_SCALARPRODUCT_STATUS_ACTIVE == s->status)
    {
      s->status = GNUNET_SCALARPRODUCT_STATUS_FAILURE;
      prepare_client_end_notification (s);
    }
  }
  destroy_cadet_session (in);
}
static void
init_notify_peer2 (void *cls, struct GNUNET_CORE_Handle *server,
                   const struct GNUNET_PeerIdentity *my_identity)
{
  struct TestMessageContext *pos = cls;

  total_server_connections++;

  pos->peer2connected = GNUNET_YES;
  if (pos->peer1notified == GNUNET_YES) /* Peer 1 has been notified of connection to peer 2 */
  {
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "Scheduling message send to peer `%s' from peer `%s' (init_notify_peer2)\n",
                GNUNET_i2s (my_identity),
                GNUNET_h2s (&pos->peer1->id.hashPubKey));
    if (NULL ==
        GNUNET_CORE_notify_transmit_ready (pos->peer1handle, GNUNET_YES, 0,
                                           TIMEOUT, &pos->peer2->id,
                                           sizeof (struct GNUNET_TestMessage),
                                           &transmit_ready, pos))
    {
      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                  "RECEIVED NULL when asking core (1) for transmission to peer `%4s'\n",
                  GNUNET_i2s (&pos->peer2->id));
      transmit_ready_failed++;
    }
    else
    {
      transmit_ready_scheduled++;
    }
  }
}
Example #9
0
/**
 * Method called whenever another peer has added us to a channel
 * the other peer initiated.
 *
 * @param cls Closure.
 * @param channel New handle to the channel.
 * @param initiator Peer that started the channel.
 * @param port Port this channel is connected to.
 * @param options channel option flags
 * @return Initial channel context for the channel
 *         (can be NULL -- that's not an error).
 */
static void *
incoming_channel (void *cls, struct GNUNET_CADET_Channel *channel,
                 const struct GNUNET_PeerIdentity *initiator,
                 const struct GNUNET_HashCode *port,
                 enum GNUNET_CADET_ChannelOption options)
{
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
              "Incoming channel from %s to peer %d:%s\n",
              GNUNET_i2s (initiator),
              (int) (long) cls, GNUNET_h2s (port));
  ok++;
  GNUNET_log (GNUNET_ERROR_TYPE_INFO, " ok: %d\n", ok);
  if ((long) cls == peers_requested - 1)
    incoming_ch = channel;
  else
  {
    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                "Incoming channel for unknown client %lu\n", (long) cls);
    GNUNET_break(0);
  }
  if (NULL != disconnect_task)
  {
    GNUNET_SCHEDULER_cancel (disconnect_task);
    disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME,
                                                    &gather_stats_and_exit,
                                                    (void *) __LINE__);
  }

  return NULL;
}
/**
 * An iterator over a set of items stored in the datastore
 * that deletes until we're happy with respect to our quota.
 *
 * @param cls closure
 * @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
 *
 * @return GNUNET_SYSERR to abort the iteration, GNUNET_OK to continue
 *         (continue on call to "next", of course),
 *         GNUNET_NO to delete the item and continue (if supported)
 */
static int
quota_processor (void *cls, const struct GNUNET_HashCode * key, uint32_t size,
                 const void *data, enum GNUNET_BLOCK_Type type,
                 uint32_t priority, uint32_t anonymity,
                 struct GNUNET_TIME_Absolute expiration, uint64_t uid)
{
  unsigned long long *need = cls;

  if (NULL == key)
    return GNUNET_SYSERR;
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Deleting %llu bytes of low-priority (%u) content `%s' of type %u at %s prior to expiration (still trying to free another %llu bytes)\n",
              (unsigned long long) (size + GNUNET_DATASTORE_ENTRY_OVERHEAD),
	      (unsigned int) priority,
              GNUNET_h2s (key), type,
	      GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_remaining (expiration),
						      GNUNET_YES),
	      *need);
  if (size + GNUNET_DATASTORE_ENTRY_OVERHEAD > *need)
    *need = 0;
  else
    *need -= size + GNUNET_DATASTORE_ENTRY_OVERHEAD;
  if (priority > 0)
    min_expiration = GNUNET_TIME_UNIT_FOREVER_ABS;
  else
    min_expiration = expiration;
  GNUNET_STATISTICS_update (stats,
                            gettext_noop ("# bytes purged (low-priority)"),
                            size, GNUNET_YES);
  GNUNET_CONTAINER_bloomfilter_remove (filter, key);
  return GNUNET_NO;
}
/**
 * Notify of all peer1's peers, once peer 2 is found, schedule connect
 * to peer two for message send.
 *
 * @param cls closure
 * @param peer peer identity this notification is about
 * @param atsi performance data for the connection
 * @param atsi_count number of ATS information included
 */
static void
connect_notify_peer2 (void *cls, const struct GNUNET_PeerIdentity *peer,
                      const struct GNUNET_ATS_Information *atsi,
                      unsigned int atsi_count)
{
  struct TestMessageContext *pos = cls;

  if (0 == memcmp (&pos->peer1->id, peer, sizeof (struct GNUNET_PeerIdentity)))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "Core connection from `%s' to `%4s' verfied, sending message!\n",
                GNUNET_i2s (&pos->peer2->id), GNUNET_h2s (&peer->hashPubKey));
    if (NULL ==
        GNUNET_CORE_notify_transmit_ready (pos->peer1handle, GNUNET_YES, 0,
                                           TIMEOUT, &pos->peer2->id,
                                           sizeof (struct GNUNET_TestMessage),
                                           &transmit_ready, pos))
    {
      /* This probably shouldn't happen, but it does (timing issue?) */
      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                  "RECEIVED NULL when asking core (1) for transmission to peer `%4s'\n",
                  GNUNET_i2s (&pos->peer2->id));
      transmit_ready_failed++;
      total_other_expected_messages--;
    }
    else
    {
      transmit_ready_scheduled++;
    }
  }
}
/**
 * Handle a GET request we've received from another peer.
 *
 * @param key the query
 * @param type requested data type
 * @param xquery extended query
 * @param xquery_size number of bytes in @a xquery
 * @param reply_bf where the reply bf is (to be) stored, possibly updated, can be NULL
 * @param reply_bf_mutator mutation value for @a reply_bf
 * @return evaluation result for the local replies
 */
enum GNUNET_BLOCK_EvaluationResult
GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key,
                          enum GNUNET_BLOCK_Type type,
                          const void *xquery,
                          size_t xquery_size,
                          struct GNUNET_CONTAINER_BloomFilter **reply_bf,
                          uint32_t reply_bf_mutator)
{
  struct GetRequestContext ctx;
  unsigned int r;

  if (NULL == datacache)
    return GNUNET_BLOCK_EVALUATION_REQUEST_VALID;
  GNUNET_STATISTICS_update (GDS_stats,
                            gettext_noop ("# GET requests given to datacache"),
                            1,
                            GNUNET_NO);
  ctx.eval = GNUNET_BLOCK_EVALUATION_REQUEST_VALID;
  ctx.key = *key;
  ctx.xquery = xquery;
  ctx.xquery_size = xquery_size;
  ctx.reply_bf = reply_bf;
  ctx.reply_bf_mutator = reply_bf_mutator;
  r = GNUNET_DATACACHE_get (datacache,
                            key,
                            type,
                            &datacache_get_iterator,
                            &ctx);
  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "DATACACHE GET for key %s completed (%d). %u results found.\n",
       GNUNET_h2s (key),
       ctx.eval,
       r);
  return ctx.eval;
}
/**
 * Route the given request via the DHT.  This includes updating
 * the bloom filter and retransmission times, building the P2P
 * message and initiating the routing operation.
 */
static void
transmit_request (struct ClientQueryRecord *cqr)
{
  int32_t reply_bf_mutator;
  struct GNUNET_CONTAINER_BloomFilter *reply_bf;
  struct GNUNET_CONTAINER_BloomFilter *peer_bf;

  GNUNET_STATISTICS_update (GDS_stats,
                            gettext_noop
                            ("# GET requests from clients injected"), 1,
                            GNUNET_NO);
  reply_bf_mutator =
      (int32_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
                                          UINT32_MAX);
  reply_bf =
      GNUNET_BLOCK_construct_bloomfilter (reply_bf_mutator, cqr->seen_replies,
                                          cqr->seen_replies_count);
  peer_bf =
      GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE,
                                         GNUNET_CONSTANTS_BLOOMFILTER_K);
  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Initiating GET for %s, replication %u, already have %u replies\n",
       GNUNET_h2s(&cqr->key), cqr->replication, cqr->seen_replies_count);
  GDS_NEIGHBOURS_handle_get (cqr->type, cqr->msg_options, cqr->replication,
                             0 /* hop count */ ,
                             &cqr->key, cqr->xquery, cqr->xquery_size, reply_bf,
                             reply_bf_mutator, peer_bf);
  GNUNET_CONTAINER_bloomfilter_free (reply_bf);
  GNUNET_CONTAINER_bloomfilter_free (peer_bf);

  /* exponential back-off for retries.
   * max GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD (15 min) */
  cqr->retry_frequency = GNUNET_TIME_STD_BACKOFF (cqr->retry_frequency);
  cqr->retry_time = GNUNET_TIME_relative_to_absolute (cqr->retry_frequency);
}
/**
 * Look for a block by directly contacting a particular peer.
 *
 * @param target peer that should have the block
 * @param query hash to query for the block
 * @param type desired type for the block
 * @param proc function to call with result
 * @param proc_cls closure for 'proc'
 * @return handle to cancel the operation
 */
struct GSF_StreamRequest *
GSF_stream_query (const struct GNUNET_PeerIdentity *target,
		  const struct GNUNET_HashCode *query,
		  enum GNUNET_BLOCK_Type type,
		  GSF_StreamReplyProcessor proc, void *proc_cls)
{
  struct StreamHandle *sh;
  struct GSF_StreamRequest *sr;

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
	      "Preparing to send query for %s via stream to %s\n",
	      GNUNET_h2s (query),
	      GNUNET_i2s (target));
  sh = get_stream (target);
  sr = GNUNET_malloc (sizeof (struct GSF_StreamRequest));
  sr->sh = sh;
  sr->proc = proc;
  sr->proc_cls = proc_cls;
  sr->type = type;
  sr->query = *query;
  GNUNET_CONTAINER_DLL_insert (sh->pending_head,
			       sh->pending_tail,
			       sr);
  if (GNUNET_YES == sh->is_ready)
    transmit_pending (sh);
  return sr;
}
Example #15
0
/**
 * Encrypt the next block of the file (and call proc and progress
 * accordingly; or of course "cont" if we have already completed
 * encoding of the entire file).
 *
 * @param te tree encoder to use
 */
void
GNUNET_FS_tree_encoder_next (struct GNUNET_FS_TreeEncoder *te)
{
  struct ContentHashKey *mychk;
  const void *pt_block;
  uint16_t pt_size;
  char iob[DBLOCK_SIZE];
  char enc[DBLOCK_SIZE];
  struct GNUNET_CRYPTO_SymmetricSessionKey sk;
  struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
  unsigned int off;

  GNUNET_assert (GNUNET_NO == te->in_next);
  te->in_next = GNUNET_YES;
  if (te->chk_tree_depth == te->current_depth)
  {
    off = CHK_PER_INODE * (te->chk_tree_depth - 1);
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "TE done, reading CHK `%s' from %u\n",
                GNUNET_h2s (&te->chk_tree[off].query), off);
    te->uri = GNUNET_new (struct GNUNET_FS_Uri);
    te->uri->type = GNUNET_FS_URI_CHK;
    te->uri->data.chk.chk = te->chk_tree[off];
    te->uri->data.chk.file_length = GNUNET_htonll (te->size);
    te->in_next = GNUNET_NO;
    te->cont (te->cls, NULL);
    return;
  }
/**
 * TEST FUNCTION
 * Remove after using.
 */
void
GDS_ROUTING_test_print (void)
{
  struct GNUNET_CONTAINER_MultiHashMapIterator *iter;
  struct RoutingTrail *trail;
  struct GNUNET_PeerIdentity print_peer;
  struct GNUNET_HashCode key_ret;
  int i;

  struct GNUNET_PeerIdentity my_identity = *GDS_NEIGHBOURS_get_id();
  print_peer = my_identity;
   FPRINTF (stderr,_("\nSUPU ***PRINTING ROUTING TABLE ***** of =%s"),GNUNET_i2s(&print_peer));
  iter =GNUNET_CONTAINER_multihashmap_iterator_create (routing_table);
  for (i = 0; i < GNUNET_CONTAINER_multihashmap_size(routing_table); i++)
  {
    if(GNUNET_YES == GNUNET_CONTAINER_multihashmap_iterator_next (iter,
                                                                  &key_ret,
                                                                  (const void **)&trail))
    {
      FPRINTF (stderr,_("\nSUPU %s, %s, %d, trail->trail_id = %s"),
              __FILE__, __func__,__LINE__, GNUNET_h2s(&trail->trail_id));
      GNUNET_memcpy (&print_peer, &trail->next_hop, sizeof (struct GNUNET_PeerIdentity));
      FPRINTF (stderr,_("\nSUPU %s, %s, %d, trail->next_hop = %s"),
              __FILE__, __func__,__LINE__, GNUNET_i2s(&print_peer));
      GNUNET_memcpy (&print_peer, &trail->prev_hop, sizeof (struct GNUNET_PeerIdentity));
      FPRINTF (stderr,_("\nSUPU %s, %s, %d, trail->prev_hop = %s"),
              __FILE__, __func__,__LINE__, GNUNET_i2s(&print_peer));
    }
  }
}
Example #17
0
/**
 * Function to process DHT string to regex matching.
 * Called on each result obtained for the DHT search.
 *
 * @param cls Closure (search context).
 * @param exp When will this value expire.
 * @param key Key of the result.
 * @param get_path Path of the get request.
 * @param get_path_length Lenght of get_path.
 * @param put_path Path of the put request.
 * @param put_path_length Length of the put_path.
 * @param type Type of the result.
 * @param size Number of bytes in data.
 * @param data Pointer to the result data.
 */
static void
dht_get_string_accept_handler (void *cls, struct GNUNET_TIME_Absolute exp,
                               const struct GNUNET_HashCode *key,
                               const struct GNUNET_PeerIdentity *get_path,
                               unsigned int get_path_length,
                               const struct GNUNET_PeerIdentity *put_path,
                               unsigned int put_path_length,
                               enum GNUNET_BLOCK_Type type,
                               size_t size, const void *data)
{
  const struct RegexAcceptBlock *block = data;
  struct RegexSearchContext *ctx = cls;
  struct REGEX_INTERNAL_Search *info = ctx->info;

  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Regex result accept for %s (key %s)\n",
       info->description, GNUNET_h2s(key));

  GNUNET_STATISTICS_update (info->stats,
			    "# regex accepting blocks found",
                            1, GNUNET_NO);
  GNUNET_STATISTICS_update (info->stats,
			    "# regex accepting block bytes found",
                            size, GNUNET_NO);
  info->callback (info->callback_cls,
                  &block->peer,
                  get_path, get_path_length,
                  put_path, put_path_length);
}
/**
 * Create a new query plan entry.
 *
 * @param cp peer with the entry
 * @param pr request with the entry
 */
void
GSF_plan_add_ (struct GSF_ConnectedPeer *cp, struct GSF_PendingRequest *pr)
{
  const struct GNUNET_PeerIdentity *id;
  struct PeerPlan *pp;
  struct GSF_PendingRequestData *prd;
  struct GSF_RequestPlan *rp;
  struct GSF_PendingRequestPlanBijection *bi;
  struct MergeContext mpc;

  GNUNET_assert (NULL != cp);
  id = GSF_connected_peer_get_identity2_ (cp);
  pp = GNUNET_CONTAINER_multihashmap_get (plans, &id->hashPubKey);
  if (NULL == pp)
  {
    pp = GNUNET_malloc (sizeof (struct PeerPlan));
    pp->plan_map = GNUNET_CONTAINER_multihashmap_create (128, GNUNET_NO);
    pp->priority_heap =
        GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MAX);
    pp->delay_heap =
        GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
    pp->cp = cp;
    GNUNET_CONTAINER_multihashmap_put (plans, 
				       &id->hashPubKey, pp,
                                       GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
  }
  mpc.merged = GNUNET_NO;
  mpc.pr = pr;
  GNUNET_CONTAINER_multihashmap_get_multiple (pp->plan_map,
                                              &GSF_pending_request_get_data_
                                              (pr)->query, &merge_pr, &mpc); // 8 MB in 'merge_pr'
  if (GNUNET_NO != mpc.merged)
    return;
  GNUNET_CONTAINER_multihashmap_get_multiple (pp->plan_map,
                                              &GSF_pending_request_get_data_
                                              (pr)->query, &merge_pr, &mpc);
  if (GNUNET_NO != mpc.merged)
    return;
  plan_count++;
  GNUNET_STATISTICS_update (GSF_stats, gettext_noop ("# query plan entries"), 1,
                            GNUNET_NO);
  prd = GSF_pending_request_get_data_ (pr);
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Planning transmission of query `%s' to peer `%s'\n",
              GNUNET_h2s (&prd->query), GNUNET_i2s (id));
  rp = GNUNET_malloc (sizeof (struct GSF_RequestPlan)); // 8 MB
  bi = GNUNET_malloc (sizeof (struct GSF_PendingRequestPlanBijection));
  bi->rp = rp;
  bi->pr = pr;
  GNUNET_CONTAINER_MDLL_insert (PR, prd->pr_head, prd->pr_tail, bi);
  GNUNET_CONTAINER_MDLL_insert (PE, rp->pe_head, rp->pe_tail, bi);
  rp->pp = pp;
  GNUNET_assert (GNUNET_YES ==
                 GNUNET_CONTAINER_multihashmap_put (pp->plan_map,
                                                    get_rp_key (rp), rp,
                                                    GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); // 8 MB
  plan (pp, rp); // +5 MB (plan/heap-insert)
}
Example #19
0
/**
 * Handler for requests of new channels.
 *
 * @param cls Identification of the client.
 * @param ccm The actual message.
 */
static void
handle_channel_create (void *cls,
                       const struct GNUNET_CADET_ChannelCreateMessage *ccm)
{
  struct CadetClient *c = cls;
  struct CadetChannel *ch;
  struct GNUNET_CADET_ClientChannelNumber chid;
  struct CadetPeer *dst;

  chid = ccm->channel_id;
  if (ntohl (chid.channel_of_client) < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
  {
    /* Channel ID not in allowed range. */
    GNUNET_break (0);
    GNUNET_SERVICE_client_drop (c->client);
    return;
  }
  ch = GNUNET_CONTAINER_multihashmap32_get (c->own_channels,
                                            ntohl (chid.channel_of_client));
  if (NULL != ch)
  {
    /* Channel ID already in use. Not allowed. */
    GNUNET_break (0);
    GNUNET_SERVICE_client_drop (c->client);
    return;
  }

  dst = GCP_get (&ccm->peer,
                 GNUNET_YES);

  /* Create channel */
  ch = GCCH_channel_local_new (c,
                               chid,
                               dst,
                               &ccm->port,
                               ntohl (ccm->opt));
  if (NULL == ch)
  {
    GNUNET_break (0);
    GNUNET_SERVICE_client_drop (c->client);
    return;
  }
  GNUNET_assert (GNUNET_YES ==
                 GNUNET_CONTAINER_multihashmap32_put (c->own_channels,
                                                      ntohl (chid.channel_of_client),
                                                      ch,
                                                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));

  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "New channel %s to %s at port %s requested by client %u\n",
       GCCH_2s (ch),
       GNUNET_i2s (&ccm->peer),
       GNUNET_h2s (&ccm->port),
       c->id);
  GNUNET_SERVICE_client_continue (c->client);
}
/**
 * Method called whenever a given peer connects.
 *
 * @param cls closure
 * @param peer peer identity this notification is about
 * @param atsi performance data for the connection
 */
static void
connect_notify_peers (void *cls, const struct GNUNET_PeerIdentity *peer,
                      const struct GNUNET_ATS_Information *atsi)
{
  struct TestMessageContext *pos = cls;

  if (0 == memcmp (peer, &pos->peer2->id, sizeof (struct GNUNET_PeerIdentity)))
  {
    pos->peer1notified = GNUNET_YES;
#if VERBOSE > 1
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "Peer `%s' notified of connection to peer `%s'\n",
                GNUNET_i2s (&pos->peer1->id), GNUNET_h2s (&peer->hashPubKey));
#endif
  }
  else
    return;

  if (pos->peer2connected == GNUNET_YES)        /* Already connected and notified of connection, send message! */
  {
#if VERBOSE > 1
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "Scheduling message send to peer `%s' from peer `%s' (init_notify_peer2)\n",
                GNUNET_i2s (&pos->peer2->id),
                GNUNET_h2s (&pos->peer1->id.hashPubKey));
#endif
    if (NULL ==
        GNUNET_CORE_notify_transmit_ready (pos->peer1handle, 0, timeout,
                                           &pos->peer2->id,
                                           sizeof (struct GNUNET_TestMessage),
                                           &transmit_ready, pos))
    {
      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                  "RECEIVED NULL when asking core (1) for transmission to peer `%4s'\n",
                  GNUNET_i2s (&pos->peer2->id));
      transmit_ready_failed++;
    }
    else
    {
      transmit_ready_scheduled++;
    }
  }
}
Example #21
0
/**
 * Print information about the given node and its edges
 * to stdout.
 *
 * @param cls closure, unused.
 * @param key hash for current state.
 * @param proof proof for current state.
 * @param accepting GNUNET_YES if this is an accepting state, GNUNET_NO if not.
 * @param num_edges number of edges leaving current state.
 * @param edges edges leaving current state.
 */
static void
print_edge (void *cls,
	    const struct GNUNET_HashCode *key,
	    const char *proof,
	    int accepting,
	    unsigned int num_edges,
	    const struct REGEX_BLOCK_Edge *edges)
{
  unsigned int i;

  printf ("%s: %s, proof: `%s'\n",
	  GNUNET_h2s (key),
	  accepting ? "ACCEPTING" : "",
	  proof);
  for (i = 0; i < num_edges; i++)
    printf ("    `%s': %s\n",
	    edges[i].label,
	    GNUNET_h2s (&edges[i].destination));
}
Example #22
0
/**
 * Iterate over the results for a particular key
 * in the datacache.
 *
 * @param h handle to the datacache
 * @param key what to look up
 * @param type entries of which type are relevant?
 * @param iter maybe NULL (to just count)
 * @param iter_cls closure for iter
 * @return the number of results found
 */
unsigned int
GNUNET_DATACACHE_get (struct GNUNET_DATACACHE_Handle *h,
                      const GNUNET_HashCode * key, enum GNUNET_BLOCK_Type type,
                      GNUNET_DATACACHE_Iterator iter, void *iter_cls)
{
  GNUNET_STATISTICS_update (h->stats, gettext_noop ("# requests received"), 1,
                            GNUNET_NO);
  LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing request for key `%s'\n",
       GNUNET_h2s (key));
  if (GNUNET_OK != GNUNET_CONTAINER_bloomfilter_test (h->filter, key))
  {
    GNUNET_STATISTICS_update (h->stats,
                              gettext_noop
                              ("# requests filtered by bloom filter"), 1,
                              GNUNET_NO);
    LOG (GNUNET_ERROR_TYPE_DEBUG, "Bloomfilter filters request for key `%s'\n",
         GNUNET_h2s (key));
    return 0;                   /* can not be present */
  }
  return h->api->get (h->api->cls, key, type, iter, iter_cls);
}
Example #23
0
/**
 * Perform an asynchronous GET operation on the DHT identified. See
 * also #GNUNET_BLOCK_evaluate.
 *
 * @param handle handle to the DHT service
 * @param type expected type of the response object
 * @param key the key to look up
 * @param desired_replication_level estimate of how many
                  nearest peers this request should reach
 * @param options routing options for this message
 * @param xquery extended query data (can be NULL, depending on type)
 * @param xquery_size number of bytes in @a xquery
 * @param iter function to call on each result
 * @param iter_cls closure for iter
 * @return handle to stop the async get
 */
struct GNUNET_DHT_GetHandle *
GNUNET_DHT_get_start (struct GNUNET_DHT_Handle *handle,
                      enum GNUNET_BLOCK_Type type, const struct GNUNET_HashCode * key,
                      uint32_t desired_replication_level,
                      enum GNUNET_DHT_RouteOption options, const void *xquery,
                      size_t xquery_size, GNUNET_DHT_GetIterator iter,
                      void *iter_cls)
{
  struct GNUNET_DHT_ClientGetMessage *get_msg;
  struct GNUNET_DHT_GetHandle *get_handle;
  size_t msize;
  struct PendingMessage *pending;

  msize = sizeof (struct GNUNET_DHT_ClientGetMessage) + xquery_size;
  if ((msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) ||
      (xquery_size >= GNUNET_SERVER_MAX_MESSAGE_SIZE))
  {
    GNUNET_break (0);
    return NULL;
  }
  LOG (GNUNET_ERROR_TYPE_DEBUG, "Sending query for %s to DHT %p\n",
       GNUNET_h2s (key), handle);
  pending = GNUNET_malloc (sizeof (struct PendingMessage) + msize);
  get_msg = (struct GNUNET_DHT_ClientGetMessage *) &pending[1];
  pending->msg = &get_msg->header;
  pending->handle = handle;
  pending->free_on_send = GNUNET_NO;
  get_msg->header.size = htons (msize);
  get_msg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET);
  get_msg->options = htonl ((uint32_t) options);
  get_msg->desired_replication_level = htonl (desired_replication_level);
  get_msg->type = htonl (type);
  get_msg->key = *key;
  get_msg->unique_id = ++handle->uid_gen;
  memcpy (&get_msg[1], xquery, xquery_size);
  GNUNET_CONTAINER_DLL_insert (handle->pending_head, handle->pending_tail,
                               pending);
  pending->in_pending_queue = GNUNET_YES;
  get_handle = GNUNET_new (struct GNUNET_DHT_GetHandle);
  get_handle->key = *key;
  get_handle->dht_handle = handle;
  get_handle->iter = iter;
  get_handle->iter_cls = iter_cls;
  get_handle->message = pending;
  get_handle->unique_id = get_msg->unique_id;
  GNUNET_CONTAINER_multihashmap_put (handle->active_requests,
                                     &get_handle->key,
                                     get_handle,
                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
  process_pending_messages (handle);
  return get_handle;
}
/**
 * Iterator over hash map entries that frees all entries
 * that match the given client and unique ID.
 *
 * @param cls unique ID and client to search for in source routes
 * @param key current key code
 * @param value value in the hash map, a ClientQueryRecord
 * @return GNUNET_YES (we should continue to iterate)
 */
static int
remove_by_unique_id (void *cls, const struct GNUNET_HashCode * key, void *value)
{
  const struct RemoveByUniqueIdContext *ctx = cls;
  struct ClientQueryRecord *record = value;

  if (record->unique_id != ctx->unique_id)
    return GNUNET_YES;
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Removing client %p's record for key %s (by unique id)\n",
              ctx->client->client_handle, GNUNET_h2s (key));
  return remove_client_records (ctx->client, key, record);
}
Example #25
0
/**
 * Function called by plugins to notify the datacache
 * about content deletions.
 *
 * @param cls closure
 * @param key key of the content that was deleted
 * @param size number of bytes that were made available
 */
static void
env_delete_notify (void *cls, const GNUNET_HashCode * key, size_t size)
{
  struct GNUNET_DATACACHE_Handle *h = cls;

  LOG (GNUNET_ERROR_TYPE_DEBUG, "Content under key `%s' discarded\n",
       GNUNET_h2s (key));
  GNUNET_assert (h->utilization >= size);
  h->utilization -= size;
  GNUNET_CONTAINER_bloomfilter_remove (h->filter, key);
  GNUNET_STATISTICS_update (h->stats, gettext_noop ("# bytes stored"), -size,
                            GNUNET_NO);
}
Example #26
0
/**
 * Store an item in the datastore.  If the item is already present,
 * the priorities are summed up and the higher expiration time and
 * lower anonymity level is used.
 *
 * @param h handle to the datastore
 * @param rid reservation ID to use (from "reserve"); use 0 if no
 *            prior reservation was made
 * @param key key for the value
 * @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 replication how often should the content be replicated to other peers?
 * @param expiration expiration time for the content
 * @param queue_priority ranking of this request in the priority queue
 * @param max_queue_size at what queue size should this request be dropped
 *        (if other requests of higher priority are in the queue)
 * @param timeout timeout for the operation
 * @param cont continuation to call when done
 * @param cont_cls closure for cont
 * @return NULL if the entry was not queued, otherwise a handle that can be used to
 *         cancel; note that even if NULL is returned, the callback will be invoked
 *         (or rather, will already have been invoked)
 */
struct GNUNET_DATASTORE_QueueEntry *
GNUNET_DATASTORE_put (struct GNUNET_DATASTORE_Handle *h, uint32_t rid,
                      const struct GNUNET_HashCode * key, size_t size,
                      const void *data, enum GNUNET_BLOCK_Type type,
                      uint32_t priority, uint32_t anonymity,
                      uint32_t replication,
                      struct GNUNET_TIME_Absolute expiration,
                      unsigned int queue_priority, unsigned int max_queue_size,
                      struct GNUNET_TIME_Relative timeout,
                      GNUNET_DATASTORE_ContinuationWithStatus cont,
                      void *cont_cls)
{
  struct GNUNET_DATASTORE_QueueEntry *qe;
  struct DataMessage *dm;
  size_t msize;
  union QueueContext qc;

  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Asked to put %u bytes of data under key `%s' for %llu ms\n", size,
       GNUNET_h2s (key),
       GNUNET_TIME_absolute_get_remaining (expiration).rel_value);
  msize = sizeof (struct DataMessage) + size;
  GNUNET_assert (msize < GNUNET_SERVER_MAX_MESSAGE_SIZE);
  qc.sc.cont = cont;
  qc.sc.cont_cls = cont_cls;
  qe = make_queue_entry (h, msize, queue_priority, max_queue_size, timeout,
                         &process_status_message, &qc);
  if (qe == NULL)
  {
    LOG (GNUNET_ERROR_TYPE_DEBUG, "Could not create queue entry for PUT\n");
    return NULL;
  }
  GNUNET_STATISTICS_update (h->stats, gettext_noop ("# PUT requests executed"),
                            1, GNUNET_NO);
  dm = (struct DataMessage *) &qe[1];
  dm->header.type = htons (GNUNET_MESSAGE_TYPE_DATASTORE_PUT);
  dm->header.size = htons (msize);
  dm->rid = htonl (rid);
  dm->size = htonl ((uint32_t) size);
  dm->type = htonl (type);
  dm->priority = htonl (priority);
  dm->anonymity = htonl (anonymity);
  dm->replication = htonl (replication);
  dm->reserved = htonl (0);
  dm->uid = GNUNET_htonll (0);
  dm->expiration = GNUNET_TIME_absolute_hton (expiration);
  dm->key = *key;
  memcpy (&dm[1], data, size);
  process_queue (h);
  return qe;
}
Example #27
0
/**
 * Stop async DHT-get.
 *
 * @param get_handle handle to the GET operation to stop
 */
void
GNUNET_DHT_get_stop (struct GNUNET_DHT_GetHandle *get_handle)
{
  struct GNUNET_DHT_Handle *handle;
  const struct GNUNET_DHT_ClientGetMessage *get_msg;
  struct GNUNET_DHT_ClientGetStopMessage *stop_msg;
  struct PendingMessage *pending;

  handle = get_handle->message->handle;
  get_msg =
      (const struct GNUNET_DHT_ClientGetMessage *) get_handle->message->msg;
  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Sending STOP for %s to DHT via %p\n",
       GNUNET_h2s (&get_msg->key), handle);
  /* generate STOP */
  pending =
      GNUNET_malloc (sizeof (struct PendingMessage) +
                     sizeof (struct GNUNET_DHT_ClientGetStopMessage));
  stop_msg = (struct GNUNET_DHT_ClientGetStopMessage *) &pending[1];
  pending->msg = &stop_msg->header;
  pending->handle = handle;
  pending->free_on_send = GNUNET_YES;
  stop_msg->header.size =
      htons (sizeof (struct GNUNET_DHT_ClientGetStopMessage));
  stop_msg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_STOP);
  stop_msg->reserved = htonl (0);
  stop_msg->unique_id = get_msg->unique_id;
  stop_msg->key = get_msg->key;
  GNUNET_CONTAINER_DLL_insert (handle->pending_head, handle->pending_tail,
                               pending);
  pending->in_pending_queue = GNUNET_YES;

  /* remove 'GET' from active status */
  GNUNET_assert (GNUNET_YES ==
                 GNUNET_CONTAINER_multihashmap_remove (handle->active_requests,
                                                       &get_handle->key,
                                                       get_handle));
  if (GNUNET_YES == get_handle->message->in_pending_queue)
  {
    GNUNET_CONTAINER_DLL_remove (handle->pending_head, handle->pending_tail,
                                 get_handle->message);
    get_handle->message->in_pending_queue = GNUNET_NO;
  }
  GNUNET_free (get_handle->message);
  GNUNET_array_grow (get_handle->seen_results,
		     get_handle->seen_results_end,
		     0);
  GNUNET_free (get_handle);
  process_pending_messages (handle);
}
/**
 * Function called once the hash computation over an
 * indexed file has completed.
 *
 * @param cls closure, our publishing context
 * @param res resulting hash, NULL on error
 */
static void
hash_for_index_val (void *cls, const struct GNUNET_HashCode * res)
{
  struct IndexInfo *ii = cls;

  ii->fhc = NULL;
  if ((res == NULL) ||
      (0 != memcmp (res, &ii->file_id, sizeof (struct GNUNET_HashCode))))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                _
                ("Hash mismatch trying to index file `%s' which has hash `%s'\n"),
                ii->filename, GNUNET_h2s (res));
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Wanted `%s'\n",
                GNUNET_h2s (&ii->file_id));
    GNUNET_SERVER_transmit_context_append_data (ii->tc, NULL, 0,
                                                GNUNET_MESSAGE_TYPE_FS_INDEX_START_FAILED);
    GNUNET_SERVER_transmit_context_run (ii->tc, GNUNET_TIME_UNIT_MINUTES);
    GNUNET_free (ii);
    return;
  }
  signal_index_ok (ii);
}
/**
 * Store an item in the datastore.
 *
 * @param cls closure
 * @param key key for the item
 * @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 replication replication-level for the content
 * @param expiration expiration time for the content
 * @param msg set to error message
 * @return GNUNET_OK on success
 */
static int
mysql_plugin_put (void *cls, const struct GNUNET_HashCode * key, uint32_t size,
                  const void *data, enum GNUNET_BLOCK_Type type,
                  uint32_t priority, uint32_t anonymity, uint32_t replication,
                  struct GNUNET_TIME_Absolute expiration, char **msg)
{
  struct Plugin *plugin = cls;
  unsigned int irepl = replication;
  unsigned int ipriority = priority;
  unsigned int ianonymity = anonymity;
  unsigned long long lexpiration = expiration.abs_value_us;
  unsigned long long lrvalue =
      (unsigned long long) GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
                                                     UINT64_MAX);
  unsigned long hashSize;
  unsigned long hashSize2;
  unsigned long lsize;
  struct GNUNET_HashCode vhash;

  if (size > MAX_DATUM_SIZE)
  {
    GNUNET_break (0);
    return GNUNET_SYSERR;
  }
  hashSize = sizeof (struct GNUNET_HashCode);
  hashSize2 = sizeof (struct GNUNET_HashCode);
  lsize = size;
  GNUNET_CRYPTO_hash (data, size, &vhash);
  if (GNUNET_OK !=
      GNUNET_MYSQL_statement_run_prepared (plugin->mc, plugin->insert_entry, NULL,
                              MYSQL_TYPE_LONG, &irepl, GNUNET_YES,
                              MYSQL_TYPE_LONG, &type, GNUNET_YES,
                              MYSQL_TYPE_LONG, &ipriority, GNUNET_YES,
                              MYSQL_TYPE_LONG, &ianonymity, GNUNET_YES,
                              MYSQL_TYPE_LONGLONG, &lexpiration, GNUNET_YES,
                              MYSQL_TYPE_LONGLONG, &lrvalue, GNUNET_YES,
                              MYSQL_TYPE_BLOB, key, hashSize, &hashSize,
                              MYSQL_TYPE_BLOB, &vhash, hashSize2, &hashSize2,
                              MYSQL_TYPE_BLOB, data, lsize, &lsize, -1))
    return GNUNET_SYSERR;
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Inserted value `%s' with size %u into gn090 table\n",
              GNUNET_h2s (key), (unsigned int) size);
  if (size > 0)
    plugin->env->duc (plugin->env->cls, size);
  return GNUNET_OK;
}
Example #30
0
/**
 * Explicitly remove some content from the database.
 * The "cont"inuation will be called with status
 * "GNUNET_OK" if content was removed, "GNUNET_NO"
 * if no matching entry was found and "GNUNET_SYSERR"
 * on all other types of errors.
 *
 * @param h handle to the datastore
 * @param key key for the value
 * @param size number of bytes in data
 * @param data content stored
 * @param queue_priority ranking of this request in the priority queue
 * @param max_queue_size at what queue size should this request be dropped
 *        (if other requests of higher priority are in the queue)
 * @param timeout how long to wait at most for a response
 * @param cont continuation to call when done
 * @param cont_cls closure for cont
 * @return NULL if the entry was not queued, otherwise a handle that can be used to
 *         cancel; note that even if NULL is returned, the callback will be invoked
 *         (or rather, will already have been invoked)
 */
struct GNUNET_DATASTORE_QueueEntry *
GNUNET_DATASTORE_remove (struct GNUNET_DATASTORE_Handle *h,
                         const struct GNUNET_HashCode * key, size_t size,
                         const void *data, unsigned int queue_priority,
                         unsigned int max_queue_size,
                         struct GNUNET_TIME_Relative timeout,
                         GNUNET_DATASTORE_ContinuationWithStatus cont,
                         void *cont_cls)
{
  struct GNUNET_DATASTORE_QueueEntry *qe;
  struct DataMessage *dm;
  size_t msize;
  union QueueContext qc;

  if (cont == NULL)
    cont = &drop_status_cont;
  LOG (GNUNET_ERROR_TYPE_DEBUG, "Asked to remove %u bytes under key `%s'\n",
       size, GNUNET_h2s (key));
  qc.sc.cont = cont;
  qc.sc.cont_cls = cont_cls;
  msize = sizeof (struct DataMessage) + size;
  GNUNET_assert (msize < GNUNET_SERVER_MAX_MESSAGE_SIZE);
  qe = make_queue_entry (h, msize, queue_priority, max_queue_size, timeout,
                         &process_status_message, &qc);
  if (qe == NULL)
  {
    LOG (GNUNET_ERROR_TYPE_DEBUG, "Could not create queue entry for REMOVE\n");
    return NULL;
  }
  GNUNET_STATISTICS_update (h->stats,
                            gettext_noop ("# REMOVE requests executed"), 1,
                            GNUNET_NO);
  dm = (struct DataMessage *) &qe[1];
  dm->header.type = htons (GNUNET_MESSAGE_TYPE_DATASTORE_REMOVE);
  dm->header.size = htons (msize);
  dm->rid = htonl (0);
  dm->size = htonl (size);
  dm->type = htonl (0);
  dm->priority = htonl (0);
  dm->anonymity = htonl (0);
  dm->uid = GNUNET_htonll (0);
  dm->expiration = GNUNET_TIME_absolute_hton (GNUNET_TIME_UNIT_ZERO_ABS);
  dm->key = *key;
  memcpy (&dm[1], data, size);
  process_queue (h);
  return qe;
}