/**
 * Compose #PeerIterateResponseMessage using the given peer and address.
 *
 * @param peer identity of the peer
 * @param address the address, NULL on disconnect
 * @return composed message
 */
static struct ValidationIterateResponseMessage *
compose_validation_iterate_response_message (const struct GNUNET_PeerIdentity *peer,
                                          const struct GNUNET_HELLO_Address *address)
{
  struct ValidationIterateResponseMessage *msg;
  size_t size;
  size_t tlen;
  size_t alen;
  char *addr;

  GNUNET_assert (NULL != peer);
  if (NULL != address)
  {
    tlen = strlen (address->transport_name) + 1;
    alen = address->address_length;
  }
  else
    tlen = alen = 0;
  size = (sizeof (struct ValidationIterateResponseMessage) + alen + tlen);
  msg = GNUNET_malloc (size);
  msg->header.size = htons (size);
  msg->header.type =
      htons (GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_VALIDATION_RESPONSE);
  msg->reserved = htonl (0);
  msg->peer = *peer;
  msg->addrlen = htonl (alen);
  msg->pluginlen = htonl (tlen);

  if (NULL != address)
  {
    msg->local_address_info = htonl((uint32_t) address->local_info);
    addr = (char *) &msg[1];
    memcpy (addr, address->address, alen);
    memcpy (&addr[alen], address->transport_name, tlen);
  }
  return msg;
}
Exemple #2
0
static void
publish_cont (void *cls, const struct GNUNET_FS_Uri *ksk_uri, const char *emsg)
{
  char *msg;
  struct GNUNET_FS_Uri *sks_uri;
  char sbuf[1024];
  char buf[1024];
  char *ret;

  if (NULL != emsg)
  {
    FPRINTF (stderr, "Error publishing: %s\n", emsg);
    err = 1;
    GNUNET_FS_stop (fs);
    return;
  }
  ret = GNUNET_STRINGS_data_to_string (&nsid, sizeof (nsid), buf, sizeof (buf));
  GNUNET_assert (NULL != ret);
  ret[0] = '\0';
  GNUNET_snprintf (sbuf, sizeof (sbuf), "gnunet://fs/sks/%s/this", buf);
  sks_uri = GNUNET_FS_uri_parse (sbuf, &msg);
  if (NULL == sks_uri)
  {
    FPRINTF (stderr, "failed to parse URI `%s': %s\n", sbuf, msg);
    err = 1;
    GNUNET_FS_stop (fs);
    GNUNET_free_non_null (msg);
    return;
  }
  ksk_search =
      GNUNET_FS_search_start (fs, ksk_uri, 1, GNUNET_FS_SEARCH_OPTION_NONE,
                              "ksk_search");
  sks_search =
      GNUNET_FS_search_start (fs, sks_uri, 1, GNUNET_FS_SEARCH_OPTION_NONE,
                              "sks_search");
  GNUNET_FS_uri_destroy (sks_uri);
}
static size_t
notify_ready (void *cls, size_t size, void *buf)
{
  struct PeerContext *p = cls;
  struct GNUNET_MessageHeader *hdr;

  th = NULL;

  if (buf == NULL)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                "Timeout occurred while waiting for transmit_ready\n");
    if (GNUNET_SCHEDULER_NO_TASK != die_task)
      GNUNET_SCHEDULER_cancel (die_task);
    die_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL);
    ok = 42;
    return 0;
  }

  GNUNET_assert (size >= TEST_MESSAGE_SIZE);
  if (buf != NULL)
  {
    memset (buf, '\0', TEST_MESSAGE_SIZE);
    hdr = buf;
    hdr->size = htons (TEST_MESSAGE_SIZE);
    hdr->type = htons (TEST_MESSAGE_TYPE);
  }

  char *ps = GNUNET_strdup (GNUNET_i2s (&p2->id));
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
              "Peer %u (`%4s') sending message with type %u and size %u bytes to peer %u (`%4s')\n",
              p2->no, ps, ntohs (hdr->type), ntohs (hdr->size), p->no,
              GNUNET_i2s (&p->id));
  GNUNET_free (ps);

  return TEST_MESSAGE_SIZE;
}
/**
 * Send a message to all of our current clients that have the right
 * options set.
 *
 * @param partner origin (or destination) of the message (used to check that this peer is
 *        known to be connected to the respective client)
 * @param msg message to multicast
 * @param can_drop can this message be discarded if the queue is too long
 * @param options mask to use
 * @param type type of the embedded message, 0 for none
 */
static void
send_to_all_clients (const struct GNUNET_PeerIdentity *partner,
                     const struct GNUNET_MessageHeader *msg,
                     int can_drop,
                     uint32_t options,
                     uint16_t type)
{
  struct GSC_Client *c;
  int tm;

  for (c = client_head; NULL != c; c = c->next)
  {
    tm = type_match (type, c);
    if (!  ( (0 != (c->options & options)) ||
	     ( (0 != (options & GNUNET_CORE_OPTION_SEND_FULL_INBOUND)) &&
	       (GNUNET_YES == tm) ) ) )
      continue;  /* neither options nor type match permit the message */
    if ( (0 != (options & GNUNET_CORE_OPTION_SEND_HDR_INBOUND)) &&
	 ( (0 != (c->options & GNUNET_CORE_OPTION_SEND_FULL_INBOUND)) ||
	   (GNUNET_YES == tm) ) )
      continue;
    if ( (0 != (options & GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND)) &&
	 (0 != (c->options & GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND)) )
      continue;
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "Sending %u message with %u bytes to client interested in messages of type %u.\n",
		options,
		ntohs (msg->size),
                (unsigned int) type);
    GNUNET_assert ( (0 == (c->options & GNUNET_CORE_OPTION_SEND_FULL_INBOUND)) ||
		    (GNUNET_YES != tm) ||
		    (GNUNET_YES ==
		     GNUNET_CONTAINER_multipeermap_contains (c->connectmap,
							     partner)) );
    send_to_client (c, msg, can_drop);
  }
}
static void
do_shutdown ()
{
  if (mhd_task_id != GNUNET_SCHEDULER_NO_TASK)
  {
    GNUNET_SCHEDULER_cancel (mhd_task_id);
    mhd_task_id = GNUNET_SCHEDULER_NO_TASK;
  }
  if (curl_task_id != GNUNET_SCHEDULER_NO_TASK)
  {
    GNUNET_SCHEDULER_cancel (curl_task_id);
    curl_task_id = GNUNET_SCHEDULER_NO_TASK;
  }
  if (NULL != mhd)
  {
    MHD_stop_daemon (mhd);
    mhd = NULL;
  }
  GNUNET_free_non_null (url);

  if (NULL != tmp_cfgfile)
    {
      if (0 != remove (tmp_cfgfile))
	GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "remove", tmp_cfgfile);
      GNUNET_free (tmp_cfgfile);
      tmp_cfgfile = NULL;
    }
  if (NULL != proxy_proc)
    {
      (void) GNUNET_OS_process_kill (proxy_proc, SIGKILL);
      GNUNET_assert (GNUNET_OK == GNUNET_OS_process_wait (proxy_proc));
      GNUNET_OS_process_destroy (proxy_proc);
      proxy_proc = NULL;
    }
  url = NULL;
  GNUNET_SCHEDULER_shutdown ();
}
int
main (int argc, char *argv_ign[])
{
  int ok = 1;

  char *const argv[] = { "test-statistics-api",
    "-c",
    "test_statistics_api_data.conf",
    NULL
  };
  struct GNUNET_GETOPT_CommandLineOption options[] = {
    GNUNET_GETOPT_OPTION_END
  };
  struct GNUNET_OS_Process *proc;
  char *binary;

  binary = GNUNET_OS_get_libexec_binary_path ("gnunet-service-statistics");
  proc =
    GNUNET_OS_start_process (GNUNET_YES, GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
			     NULL, NULL, NULL,
			     binary,
			     "gnunet-service-statistics",
			     "-c", "test_statistics_api_data.conf", NULL);
  GNUNET_assert (NULL != proc);
  GNUNET_PROGRAM_run (3, argv, "test-statistics-api", "nohelp", options, &run,
                      &ok);
  if (0 != GNUNET_OS_process_kill (proc, GNUNET_TERM_SIG))
  {
    GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
    ok = 1;
  }
  GNUNET_OS_process_wait (proc);
  GNUNET_OS_process_destroy (proc);
  proc = NULL;
  GNUNET_free (binary);
  return ok;
}
Exemple #7
0
/**
 * Store an item in the datastore.
 *
 * @param h handle to the datacache
 * @param key key to store data under
 * @param size number of bytes in data
 * @param data data to store
 * @param type type of the value
 * @param discard_time when to discard the value in any case
 * @param path_info_len number of entries in 'path_info'
 * @param path_info a path through the network
 * @return GNUNET_OK on success, GNUNET_SYSERR on error, GNUNET_NO if duplicate
 */
int
GNUNET_DATACACHE_put (struct GNUNET_DATACACHE_Handle *h,
                      const struct GNUNET_HashCode * key, size_t size,
                      const char *data, enum GNUNET_BLOCK_Type type,
                      struct GNUNET_TIME_Absolute discard_time,
		      unsigned int path_info_len,
		      const struct GNUNET_PeerIdentity *path_info)
{
  ssize_t used;

  used = h->api->put (h->api->cls, key, 
		      size, data, 
		      type, discard_time,
		      path_info_len, path_info);
  if (-1 == used)
  {
    GNUNET_break (0);
    return GNUNET_SYSERR;
  }
  if (0 == used)
  {
    /* duplicate */
    return GNUNET_NO;
  }
  LOG (GNUNET_ERROR_TYPE_DEBUG, "Stored data under key `%s' in cache\n",
       GNUNET_h2s (key));
  GNUNET_STATISTICS_update (h->stats, gettext_noop ("# bytes stored"), size,
                            GNUNET_NO);
  GNUNET_STATISTICS_update (h->stats, gettext_noop ("# items stored"), 1,
                            GNUNET_NO);
  if (NULL != h->filter)
    GNUNET_CONTAINER_bloomfilter_add (h->filter, key);
  while (h->utilization + used > h->env.quota)
    GNUNET_assert (GNUNET_OK == h->api->del (h->api->cls));
  h->utilization += used;
  return GNUNET_OK;
}
/**
 * Add a host to the list and notify clients about this event
 *
 * @param identity the identity of the host
 * @return the HostEntry
 */
static struct HostEntry *
add_host_to_known_hosts (const struct GNUNET_PeerIdentity *identity)
{
  struct HostEntry *entry;
  struct ReadHostFileContext r;
  char *fn;

  entry = GNUNET_CONTAINER_multipeermap_get (hostmap, identity);
  if (NULL == entry)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "Adding new peer `%s'\n",
                GNUNET_i2s (identity));
    GNUNET_STATISTICS_update (stats, gettext_noop ("# peers known"), 1,
			      GNUNET_NO);
    entry = GNUNET_new (struct HostEntry);
    entry->identity = *identity;
    GNUNET_assert (GNUNET_OK ==
                   GNUNET_CONTAINER_multipeermap_put (hostmap,
                                                      &entry->identity,
                                                      entry,
                                                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
    notify_all (entry);
    fn = get_host_filename (identity);
    if (NULL != fn)
    {
      read_host_file (fn, GNUNET_YES, &r);
      if (NULL != r.hello)
      	update_hello (identity, r.hello);
      if (NULL != r.friend_only_hello)
      	update_hello (identity, r.friend_only_hello);
      GNUNET_free_non_null (r.hello);
      GNUNET_free_non_null (r.friend_only_hello);
      GNUNET_free (fn);
    }
  }
Exemple #9
0
/**
 * Handler for messages received from the GNS service
 *
 * @param cls the `struct GNUNET_GNS_Handle *`
 * @param loookup_msg the incoming message
 */
static void
handle_result (void *cls,
               const struct LookupResultMessage *lookup_msg)
{
    struct GNUNET_GNS_Handle *handle = cls;
    size_t mlen = ntohs (lookup_msg->header.size) - sizeof (*lookup_msg);
    uint32_t rd_count = ntohl (lookup_msg->rd_count);
    struct GNUNET_GNSRECORD_Data rd[rd_count];
    uint32_t r_id = ntohl (lookup_msg->id);
    struct GNUNET_GNS_LookupRequest *lr;
    GNUNET_GNS_LookupResultProcessor proc;
    void *proc_cls;

    LOG (GNUNET_ERROR_TYPE_DEBUG,
         "Received lookup reply from GNS service (%u records)\n",
         (unsigned int) rd_count);
    for (lr = handle->lookup_head; NULL != lr; lr = lr->next)
        if (lr->r_id == r_id)
            break;
    if (NULL == lr)
        return;
    proc = lr->lookup_proc;
    proc_cls = lr->proc_cls;
    GNUNET_CONTAINER_DLL_remove (handle->lookup_head,
                                 handle->lookup_tail,
                                 lr);
    GNUNET_free (lr);
    GNUNET_assert (GNUNET_OK ==
                   GNUNET_GNSRECORD_records_deserialize (mlen,
                           (const char*) &lookup_msg[1],
                           rd_count,
                           rd));
    proc (proc_cls,
          rd_count,
          rd);
}
/**
 * Initialize framework and start test
 *
 * @param cls closure
 * @param cfg configuration of the peer that was started
 * @param peer identity of the peer that was created
 */
static void
run (void *cls, 
     const struct GNUNET_CONFIGURATION_Handle *cfg,
     struct GNUNET_TESTING_Peer *peer)
{
  struct GNUNET_PeerIdentity id;

  GNUNET_TESTING_peer_get_identity (peer, &id);
  config = cfg;
  peer2_listen_socket = 
      GNUNET_STREAM_listen (config, 10, &stream_listen_cb, &peer_data[1],
			    GNUNET_STREAM_OPTION_SIGNAL_LISTEN_SUCCESS,
                            &stream_connect,
                            GNUNET_STREAM_OPTION_MAX_PAYLOAD_SIZE,
                            payload_size[payload_size_index],
                            GNUNET_STREAM_OPTION_END);
  GNUNET_assert (NULL != peer2_listen_socket);
  peer_data[0].id = id;
  peer_data[1].id = id;
  abort_task =
      GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
                                    (GNUNET_TIME_UNIT_SECONDS, 300), &do_abort,
                                    NULL);
}
Exemple #11
0
/**
 * Get a random value from the datastore for content replication.
 * Returns a single, random value among those with the highest
 * replication score, lowering positive replication scores by one for
 * the chosen value (if only content with a replication score exists,
 * a random value is returned and replication scores are not changed).
 *
 * @param h handle to the datastore
 * @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 a random value; it
 *        will be called once with a value (if available)
 *        and always once with a value of NULL.
 * @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_for_replication (struct GNUNET_DATASTORE_Handle *h,
                                      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 GNUNET_MessageHeader *m;
  union QueueContext qc;

  GNUNET_assert (NULL != proc);
  LOG (GNUNET_ERROR_TYPE_DEBUG, "Asked to get replication entry in %llu ms\n",
       (unsigned long long) timeout.rel_value);
  qc.rc.proc = proc;
  qc.rc.proc_cls = proc_cls;
  qe = make_queue_entry (h, sizeof (struct GNUNET_MessageHeader),
                         queue_priority, max_queue_size, timeout,
                         &process_result_message, &qc);
  if (qe == NULL)
  {
    LOG (GNUNET_ERROR_TYPE_DEBUG,
         "Could not create queue entry for GET REPLICATION\n");
    return NULL;
  }
  GNUNET_STATISTICS_update (h->stats,
                            gettext_noop
                            ("# GET REPLICATION requests executed"), 1,
                            GNUNET_NO);
  m = (struct GNUNET_MessageHeader *) &qe[1];
  m->type = htons (GNUNET_MESSAGE_TYPE_DATASTORE_GET_REPLICATION);
  m->size = htons (sizeof (struct GNUNET_MessageHeader));
  process_queue (h);
  return qe;
}
Exemple #12
0
/**
 * Write the pseudonym infomation into a file
 * @param cfg configuration to use
 * @param nsid hash code of a pseudonym
 * @param meta meta data to be written into a file
 * @param ranking ranking of a pseudonym
 * @param ns_name non-unique name of a pseudonym
 */
static void
write_pseudonym_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
                      const struct GNUNET_HashCode * nsid,
                      const struct GNUNET_CONTAINER_MetaData *meta,
                      int32_t ranking, const char *ns_name)
{
  char *fn;
  struct GNUNET_BIO_WriteHandle *fileW;

  fn = get_data_filename (cfg, PS_METADATA_DIR, nsid);
  GNUNET_assert (fn != NULL);
  fileW = GNUNET_BIO_write_open (fn);
  if (NULL != fileW)
  {
    if ((GNUNET_OK != GNUNET_BIO_write_int32 (fileW, ranking)) ||
        (GNUNET_OK != GNUNET_BIO_write_string (fileW, ns_name)) ||
        (GNUNET_OK != GNUNET_BIO_write_meta_data (fileW, meta)))
    {
      (void) GNUNET_BIO_write_close (fileW);
      GNUNET_break (GNUNET_OK == GNUNET_DISK_directory_remove (fn));
      GNUNET_free (fn);
      return;
    }
    if (GNUNET_OK != GNUNET_BIO_write_close (fileW))
    {
      GNUNET_break (GNUNET_OK == GNUNET_DISK_directory_remove (fn));
      GNUNET_free (fn);
      return;
    }
  }
  GNUNET_free (fn);
  /* create entry for pseudonym name in names */
  if (ns_name != NULL)
    GNUNET_free_non_null (GNUNET_PSEUDONYM_name_uniquify (cfg, nsid, ns_name,
        NULL));
}
/**
 * Add a host to the persistent list.  This method operates in
 * semi-reliable mode: if the transmission is not completed by
 * the time 'GNUNET_PEERINFO_disconnect' is called, it will be
 * aborted.  Furthermore, if a second HELLO is added for the
 * same peer before the first one was transmitted, PEERINFO may
 * merge the two HELLOs prior to transmission to the service.
 *
 * @param h handle to the peerinfo service
 * @param hello the verified (!) HELLO message
 * @param cont continuation to call when done, NULL is allowed
 * @param cont_cls closure for 'cont'
 * @return handle to cancel add operation; all pending
 *         'add' operations will be cancelled automatically
 *        on disconnect, so it is not necessary to keep this
 *        handle (unless 'cont' is NULL and at some point
 *        calling 'cont' must be prevented)
 */
struct GNUNET_PEERINFO_AddContext *
GNUNET_PEERINFO_add_peer (struct GNUNET_PEERINFO_Handle *h,
                          const struct GNUNET_HELLO_Message *hello,
			  GNUNET_PEERINFO_Continuation cont,
			  void *cont_cls)
{
  uint16_t hs = GNUNET_HELLO_size (hello);
  struct GNUNET_PEERINFO_AddContext *ac;
  struct GNUNET_PeerIdentity peer;

  GNUNET_assert (GNUNET_OK == GNUNET_HELLO_get_id (hello, &peer));
  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Adding peer `%s' to PEERINFO database (%u bytes of `%s')\n",
       GNUNET_i2s (&peer), hs, "HELLO");
  ac = GNUNET_malloc (sizeof (struct GNUNET_PEERINFO_AddContext) + hs);
  ac->h = h;
  ac->size = hs;
  ac->cont = cont;
  ac->cont_cls = cont_cls;
  memcpy (&ac[1], hello, hs);
  GNUNET_CONTAINER_DLL_insert_tail (h->ac_head, h->ac_tail, ac);
  trigger_transmit (h);
  return ac;
}
/**
 * Get (or create) a stream to talk to the given peer.
 *
 * @param target peer we want to communicate with
 */
static struct StreamHandle *
get_stream (const struct GNUNET_PeerIdentity *target)
{
  struct StreamHandle *sh;

  sh = GNUNET_CONTAINER_multihashmap_get (stream_map,
					  &target->hashPubKey);
  if (NULL != sh)
  {
    if (GNUNET_SCHEDULER_NO_TASK != sh->timeout_task)
    {
      GNUNET_SCHEDULER_cancel (sh->timeout_task);
      sh->timeout_task = GNUNET_SCHEDULER_NO_TASK;
    }
    return sh;
  }
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
	      "Creating stream to %s\n",
	      GNUNET_i2s (target));
  sh = GNUNET_malloc (sizeof (struct StreamHandle));
  sh->mst = GNUNET_SERVER_mst_create (&reply_cb,
				      sh);
  sh->waiting_map = GNUNET_CONTAINER_multihashmap_create (512, GNUNET_YES);
  sh->target = *target;
  sh->stream = GNUNET_STREAM_open (GSF_cfg,
				   &sh->target,
				   GNUNET_APPLICATION_TYPE_FS_BLOCK_TRANSFER,
				   &stream_ready_cb, sh,
				   GNUNET_STREAM_OPTION_END);
  GNUNET_assert (GNUNET_OK ==
		 GNUNET_CONTAINER_multihashmap_put (stream_map,
						    &sh->target.hashPubKey,
						    sh,
						    GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
  return sh;
}
/**
 * Update the priority for a particular key in the datastore.  If
 * the expiration time in value is different than the time found in
 * the datastore, the higher value should be kept.  For the
 * anonymity level, the lower value is to be used.  The specified
 * priority should be added to the existing priority, ignoring the
 * priority in value.
 *
 * @param cls our "struct Plugin*"
 * @param uid unique identifier of the datum
 * @param delta by how much should the priority
 *     change?  If priority + delta < 0 the
 *     priority should be set to 0 (never go
 *     negative).
 * @param expire new expiration time should be the
 *     MAX of any existing expiration time and
 *     this value
 * @param msg set to error message
 * @return GNUNET_OK on success
 */
static int
heap_plugin_update (void *cls, 
		    uint64_t uid, 
		    int delta,
		    struct GNUNET_TIME_Absolute expire, char **msg)
{
  struct Plugin *plugin = cls;
  struct Value *value;

  value = (struct Value*) (long) uid;
  GNUNET_assert (NULL != value);
  if (value->expiration.abs_value != expire.abs_value)
  {
    value->expiration = expire;
    GNUNET_CONTAINER_heap_update_cost (plugin->by_expiration,
				       value->expire_heap,
				       expire.abs_value);
  }
  if ( (delta < 0) && (value->priority < - delta) )
    value->priority = 0;
  else
    value->priority += delta;
  return GNUNET_OK;
}
/**
 * Copy "frequent" metadata items over to the
 * target metadata container, free the counters.
 *
 * @param cls the 'struct TrimContext'
 * @param key key of the entry
 * @param value the 'struct KeywordCounter'
 * @return GNUNET_YES (always)
 */
static int
migrate_and_drop_metadata (void *cls, const GNUNET_HashCode * key, void *value)
{
  struct TrimContext *tc = cls;
  struct MetaCounter *counter = value;

  if (counter->count >= tc->move_threshold)
  {
    if (NULL == tc->pos->meta)
      tc->pos->meta = GNUNET_CONTAINER_meta_data_create ();
    GNUNET_CONTAINER_meta_data_insert (tc->pos->meta,
				       counter->plugin_name,
				       counter->type,
				       counter->format,
				       counter->data_mime_type, counter->data,
				       counter->data_size); 
  }
  GNUNET_assert (GNUNET_YES ==
		 GNUNET_CONTAINER_multihashmap_remove (tc->metacounter,
						       key,
						       counter));
  GNUNET_free (counter);
  return GNUNET_YES;
}
/**
 * Add the given keyword to the keyword statistics tracker.
 *
 * @param cls the multihashmap we store the keyword counters in
 * @param keyword the keyword to count
 * @param is_mandatory ignored
 * @return always GNUNET_OK
 */
static int
add_to_keyword_counter (void *cls, const char *keyword, int is_mandatory)
{
  struct GNUNET_CONTAINER_MultiHashMap *mcm = cls;
  struct KeywordCounter *cnt;
  GNUNET_HashCode hc;
  size_t klen;

  klen = strlen (keyword) + 1;
  GNUNET_CRYPTO_hash (keyword, klen - 1, &hc);
  cnt = GNUNET_CONTAINER_multihashmap_get (mcm, &hc);
  if (cnt == NULL)
  {
    cnt = GNUNET_malloc (sizeof (struct KeywordCounter) + klen);
    cnt->value = (const char *) &cnt[1];
    memcpy (&cnt[1], keyword, klen);
    GNUNET_assert (GNUNET_OK ==
		   GNUNET_CONTAINER_multihashmap_put (mcm, 
						      &hc, cnt,
						      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
  }
  cnt->count++;
  return GNUNET_OK;
}
Exemple #18
0
/**
 * Store an item in the datastore.
 *
 * @param h handle to the datacache
 * @param key key to store data under
 * @param size number of bytes in data
 * @param data data to store
 * @param type type of the value
 * @param discard_time when to discard the value in any case
 * @return GNUNET_OK on success, GNUNET_SYSERR on error (full, etc.)
 */
int
GNUNET_DATACACHE_put (struct GNUNET_DATACACHE_Handle *h,
                      const GNUNET_HashCode * key, size_t size,
                      const char *data, enum GNUNET_BLOCK_Type type,
                      struct GNUNET_TIME_Absolute discard_time)
{
  uint32_t used;

  used = h->api->put (h->api->cls, key, size, data, type, discard_time);
  if (used == 0)
  {
    GNUNET_break (0);
    return GNUNET_SYSERR;
  }
  LOG (GNUNET_ERROR_TYPE_DEBUG, "Stored data under key `%s' in cache\n",
       GNUNET_h2s (key));
  GNUNET_STATISTICS_update (h->stats, gettext_noop ("# bytes stored"), size,
                            GNUNET_NO);
  GNUNET_CONTAINER_bloomfilter_add (h->filter, key);
  while (h->utilization + used > h->env.quota)
    GNUNET_assert (GNUNET_OK == h->api->del (h->api->cls));
  h->utilization += used;
  return GNUNET_OK;
}
Exemple #19
0
/**
 * The given request hit its timeout.  Remove from the
 * doubly-linked list and call the respective continuation.
 *
 * @param cls the transmit handle of the request that timed out
 * @param tc context, can be NULL (!)
 */
static void
transmission_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct PeerRecord *pr = cls;
  struct GNUNET_CORE_Handle *h = pr->ch;
  struct GNUNET_CORE_TransmitHandle *th;

  pr->timeout_task = GNUNET_SCHEDULER_NO_TASK;
  if (GNUNET_SCHEDULER_NO_TASK != pr->ntr_task)
  {
    GNUNET_SCHEDULER_cancel (pr->ntr_task);
    pr->ntr_task = GNUNET_SCHEDULER_NO_TASK;
  }
  th = &pr->th;
  th->peer = NULL;
  if ((NULL != pr->prev) || (NULL != pr->next) || (pr == h->ready_peer_head))
  {
    /* the request that was 'approved' by core was
     * canceled before it could be transmitted; remove
     * us from the 'ready' list */
    GNUNET_CONTAINER_DLL_remove (h->ready_peer_head, h->ready_peer_tail, pr);
  }
  if (NULL != th->cm)
  {
     /* we're currently in the control queue, remove */
    GNUNET_CONTAINER_DLL_remove (h->control_pending_head,
                                 h->control_pending_tail, th->cm);
    GNUNET_free (th->cm);
  }
  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Signalling timeout of request for transmission to peer `%s' via CORE\n",
       GNUNET_i2s (&pr->peer));
  trigger_next_request (h, GNUNET_NO);

  GNUNET_assert (0 == th->get_message (th->get_message_cls, 0, NULL));
}
/**
 * Calculate when we would like to send the next HELLO to this
 * peer and ask for it.
 *
 * @param cls for which peer to schedule the HELLO
 * @param tc task context
 */
static void
schedule_next_hello (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct Peer *pl = cls;
  struct FindAdvHelloContext fah;
  size_t next_want;
  struct GNUNET_TIME_Relative delay;

  pl->hello_delay_task = GNUNET_SCHEDULER_NO_TASK;
  GNUNET_assert (GNUNET_YES == pl->is_connected);
  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
    return;                     /* we're out of here */
  if (pl->hello_req != NULL)
    return;                     /* did not finish sending the previous one */
  /* find applicable HELLOs */
  fah.peer = pl;
  fah.result = NULL;
  fah.max_size = GNUNET_SERVER_MAX_MESSAGE_SIZE - 1;
  fah.next_adv = GNUNET_TIME_UNIT_FOREVER_REL;
  GNUNET_CONTAINER_multihashmap_iterate (peers, &find_advertisable_hello, &fah);
  pl->hello_delay_task =
      GNUNET_SCHEDULER_add_delayed (fah.next_adv, &schedule_next_hello, pl);
  if (fah.result == NULL)
    return;
  next_want = GNUNET_HELLO_size (fah.result->hello);
  delay = GNUNET_TIME_absolute_get_remaining (pl->next_hello_allowed);
  if (delay.rel_value == 0)
  {
    /* now! */
    pl->hello_req =
        GNUNET_CORE_notify_transmit_ready (handle, GNUNET_YES, 0,
                                           GNUNET_CONSTANTS_SERVICE_TIMEOUT,
                                           &pl->pid, next_want,
                                           &hello_advertising_ready, pl);
  }
}
Exemple #21
0
/**
 * Function called to notify a client about the socket
 * begin ready to queue the message.  "buf" will be
 * NULL and "size" zero if the socket was closed for
 * writing in the meantime.
 *
 * @param cls closure of type "struct TransmitGetResponseContext*"
 * @param size number of bytes available in buf
 * @param buf where the callee should write the message
 * @return number of bytes written to buf
 */
static size_t
transmit_for_response (void *cls, size_t size, void *buf)
{
  struct TransmitGetResponseContext *tc = cls;
  uint16_t msize;

  tc->client->tag = NULL;
  msize = ntohs (tc->hdr->size);
  if (NULL == buf)
  {
    LOG (GNUNET_ERROR_TYPE_DEBUG,
         _("Could not submit request, not expecting to receive a response.\n"));
    if (NULL != tc->rn)
      tc->rn (tc->rn_cls, NULL);
    GNUNET_free (tc);
    return 0;
  }
  GNUNET_assert (size >= msize);
  memcpy (buf, tc->hdr, msize);
  GNUNET_CLIENT_receive (tc->client, tc->rn, tc->rn_cls,
                         GNUNET_TIME_absolute_get_remaining (tc->timeout));
  GNUNET_free (tc);
  return msize;
}
Exemple #22
0
/**
 * Function that queries MHD's select sets and
 * starts the task waiting for them.
 */
static struct GNUNET_SCHEDULER_Task *
prepare_daemon (struct MHD_Daemon *daemon_handle)
{
  struct GNUNET_SCHEDULER_Task * ret;
  fd_set rs;
  fd_set ws;
  fd_set es;
  struct GNUNET_NETWORK_FDSet *wrs;
  struct GNUNET_NETWORK_FDSet *wws;
  int max;
  MHD_UNSIGNED_LONG_LONG timeout;
  int haveto;
  struct GNUNET_TIME_Relative tv;

  FD_ZERO (&rs);
  FD_ZERO (&ws);
  FD_ZERO (&es);
  wrs = GNUNET_NETWORK_fdset_create ();
  wws = GNUNET_NETWORK_fdset_create ();
  max = -1;
  GNUNET_assert (MHD_YES == MHD_get_fdset (daemon_handle, &rs, &ws, &es, &max));
  haveto = MHD_get_timeout (daemon_handle, &timeout);
  if (haveto == MHD_YES)
    tv.rel_value_us = (uint64_t) timeout * 1000LL;
  else
    tv = GNUNET_TIME_UNIT_FOREVER_REL;
  GNUNET_NETWORK_fdset_copy_native (wrs, &rs, max + 1);
  GNUNET_NETWORK_fdset_copy_native (wws, &ws, max + 1);
  ret =
      GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH,
				   tv, wrs, wws,
                                   &run_daemon, daemon_handle);
  GNUNET_NETWORK_fdset_destroy (wrs);
  GNUNET_NETWORK_fdset_destroy (wws);
  return ret;
}
Exemple #23
0
/**
 * We got disconnected from the service and thus all of the
 * pending send callbacks will never be confirmed.  Clean up.
 *
 * @param cls the 'struct GNUNET_DV_ServiceHandle'
 * @param key a peer identity
 * @param value a `struct ConnectedPeer` to clean up
 * @return #GNUNET_OK (continue to iterate)
 */
static int
cleanup_send_cb (void *cls,
		 const struct GNUNET_PeerIdentity *key,
		 void *value)
{
  struct GNUNET_DV_ServiceHandle *sh = cls;
  struct ConnectedPeer *peer = value;
  struct GNUNET_DV_TransmitHandle *th;

  GNUNET_assert (GNUNET_YES ==
		 GNUNET_CONTAINER_multipeermap_remove (sh->peers,
						       key,
						       peer));
  sh->disconnect_cb (sh->cls,
                     key);
  while (NULL != (th = peer->head))
  {
    GNUNET_CONTAINER_DLL_remove (peer->head, peer->tail, th);
    th->cb (th->cb_cls, GNUNET_SYSERR);
    GNUNET_free (th);
  }
  GNUNET_free (peer);
  return GNUNET_OK;
}
/**
 * Select a subset of the items in the datastore and call
 * the given processor for the item.
 *
 * @param cls our plugin context
 * @param offset offset of the result (modulo num-results);
 *               specific ordering does not matter for the offset
 * @param type entries of which type should be considered?
 *        Use 0 for any type.
 * @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
 */
static void
sqlite_plugin_get_zero_anonymity (void *cls, uint64_t offset,
                                  enum GNUNET_BLOCK_Type type,
                                  PluginDatumProcessor proc, void *proc_cls)
{
  struct Plugin *plugin = cls;
  sqlite3_stmt *stmt;

  GNUNET_assert (type != GNUNET_BLOCK_TYPE_ANY);
  stmt = plugin->selZeroAnon;
  if ((SQLITE_OK != sqlite3_bind_int (stmt, 1, type)) ||
      (SQLITE_OK != sqlite3_bind_int64 (stmt, 2, offset)))
  {
    LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                "sqlite3_bind_XXXX");
    if (SQLITE_OK != sqlite3_reset (stmt))
      LOG_SQLITE (plugin, NULL,
                  GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                  "sqlite3_reset");
    proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
    return;
  }
  execute_get (plugin, stmt, proc, proc_cls);
}
static void
connect_notify (void *cls, const struct GNUNET_PeerIdentity *peer)
{
  struct PeerContext *pc = cls;

  if (0 == memcmp (&pc->id, peer, sizeof (struct GNUNET_PeerIdentity)))
    return;                     /* loopback */
  GNUNET_assert (pc->connect_status == 0);
  pc->connect_status = 1;
  if (pc == &p1)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "Encrypted connection established to peer `%4s'\n",
                GNUNET_i2s (peer));
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "Asking core (1) for transmission to peer `%4s'\n",
                GNUNET_i2s (&p2.id));
    if (err_task != NULL)
      GNUNET_SCHEDULER_cancel (err_task);
    err_task =
        GNUNET_SCHEDULER_add_delayed (TIMEOUT, &terminate_task_error, NULL);
    start_time = GNUNET_TIME_absolute_get ();
    running = GNUNET_YES;
    measure_task =
        GNUNET_SCHEDULER_add_delayed (MEASUREMENT_LENGTH, &measurement_stop,
                                      NULL);

    GNUNET_break (NULL !=
                  (p1.nth =
                   GNUNET_CORE_notify_transmit_ready (p1.ch, GNUNET_NO,
                                                      GNUNET_CORE_PRIO_BEST_EFFORT,
                                                      TIMEOUT, &p2.id,
                                                      MESSAGESIZE,
                                                      &transmit_ready, &p1)));
  }
}
/**
 * Test killing via pipe.
 */
static int
check_kill ()
{
  hello_pipe_stdin = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_YES, GNUNET_NO);
  hello_pipe_stdout = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES);
  if ((hello_pipe_stdout == NULL) || (hello_pipe_stdin == NULL))
  {
    return 1;
  }
  proc =
    GNUNET_OS_start_process (GNUNET_YES, hello_pipe_stdin, hello_pipe_stdout, "cat",
			     "gnunet-service-resolver", "-", NULL); 
  sleep (1); /* give process time to start and open pipe */
  if (0 != GNUNET_OS_process_kill (proc, SIGTERM))
  {
    GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
  }
  GNUNET_assert (GNUNET_OK == GNUNET_OS_process_wait (proc));
  GNUNET_OS_process_destroy (proc);
  proc = NULL;
  GNUNET_DISK_pipe_close (hello_pipe_stdout);
  GNUNET_DISK_pipe_close (hello_pipe_stdin);
  return 0;
}
/**
 * run: load configuration options and schedule test to run (start peergroup)
 * @param cls closure
 * @param args argv
 * @param cfgfile configuration file name (can be NULL)
 * @param cfg configuration handle
 */
static void
run (void *cls, char *const *args, const char *cfgfile,
     const struct GNUNET_CONFIGURATION_Handle *cfg)
{
  struct GNUNET_TESTING_Host *hosts;

  ok = GNUNET_NO;
  total_connections = 0;
  failed_connections = 0;
  testing_cfg = GNUNET_CONFIGURATION_dup (cfg);

  GNUNET_log_setup ("test_mesh_2dtorus",
                    "WARNING",
                    NULL);


  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Starting daemons.\n");
  if (GNUNET_OK !=
      GNUNET_CONFIGURATION_get_value_number (testing_cfg, "testing_old",
                                             "num_peers", &num_peers))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                "Option TESTING:NUM_PEERS is required!\n");
    return;
  }

  hosts = GNUNET_TESTING_hosts_load (testing_cfg);

  pg = GNUNET_TESTING_peergroup_start (testing_cfg, num_peers, TIMEOUT,
                                       &connect_cb, &peergroup_ready, NULL,
                                       hosts);
  GNUNET_assert (pg != NULL);
  shutdown_handle =
    GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
                                    &shutdown_task, NULL);
}
static int
testMap (int i)
{
  struct GNUNET_CONTAINER_MultiPeerMap *m;
  struct GNUNET_PeerIdentity k1;
  struct GNUNET_PeerIdentity k2;
  struct GNUNET_CONTAINER_MultiPeerMapIterator *iter;
  struct GNUNET_PeerIdentity key_ret;
  const char *ret;
  int j;

  CHECK (NULL != (m = GNUNET_CONTAINER_multipeermap_create (i, GNUNET_NO)));
  memset (&k1, 0, sizeof (k1));
  memset (&k2, 1, sizeof (k2));
  CHECK (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (m, &k1));
  CHECK (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (m, &k2));
  CHECK (GNUNET_NO == GNUNET_CONTAINER_multipeermap_remove (m, &k1, NULL));
  CHECK (GNUNET_NO == GNUNET_CONTAINER_multipeermap_remove (m, &k2, NULL));
  CHECK (NULL == GNUNET_CONTAINER_multipeermap_get (m, &k1));
  CHECK (NULL == GNUNET_CONTAINER_multipeermap_get (m, &k2));
  CHECK (0 == GNUNET_CONTAINER_multipeermap_remove_all (m, &k1));
  CHECK (0 == GNUNET_CONTAINER_multipeermap_size (m));
  CHECK (0 == GNUNET_CONTAINER_multipeermap_iterate (m, NULL, NULL));
  CHECK (0 == GNUNET_CONTAINER_multipeermap_get_multiple (m, &k1, NULL, NULL));

  CHECK (GNUNET_OK ==
         GNUNET_CONTAINER_multipeermap_put (m, &k1, "v1",
                                            GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE));
  CHECK (1 == GNUNET_CONTAINER_multipeermap_size (m));
  ret = GNUNET_CONTAINER_multipeermap_get (m, &k1);
  GNUNET_assert (ret != NULL);
  CHECK (0 == strcmp ("v1", ret));
  CHECK (GNUNET_NO ==
         GNUNET_CONTAINER_multipeermap_put (m, &k1, "v1",
                                            GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE));
  CHECK (1 == GNUNET_CONTAINER_multipeermap_size (m));
  CHECK (GNUNET_OK ==
         GNUNET_CONTAINER_multipeermap_put (m, &k1, "v2",
                                            GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
  CHECK (GNUNET_OK ==
         GNUNET_CONTAINER_multipeermap_put (m, &k1, "v3",
                                            GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
  CHECK (3 == GNUNET_CONTAINER_multipeermap_size (m));
  CHECK (GNUNET_OK == GNUNET_CONTAINER_multipeermap_remove (m, &k1, "v3"));
  CHECK (2 == GNUNET_CONTAINER_multipeermap_size (m));
  CHECK (GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains (m, &k1));
  CHECK (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (m, &k2));
  CHECK (2 == GNUNET_CONTAINER_multipeermap_get_multiple (m, &k1, NULL, NULL));
  CHECK (0 == GNUNET_CONTAINER_multipeermap_get_multiple (m, &k2, NULL, NULL));
  CHECK (2 == GNUNET_CONTAINER_multipeermap_iterate (m, NULL, NULL));
  iter = GNUNET_CONTAINER_multipeermap_iterator_create (m);
  CHECK (GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter, &key_ret, (const void **)&ret));
  CHECK (0 == memcmp (&key_ret, &k1, sizeof (key_ret)));
  CHECK (GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter, &key_ret, (const void **)&ret));
  CHECK (0 == memcmp (&key_ret, &k1, sizeof (key_ret)));
  CHECK (GNUNET_NO == GNUNET_CONTAINER_multipeermap_iterator_next (iter, NULL, NULL));
  GNUNET_free (iter);

  CHECK (2 == GNUNET_CONTAINER_multipeermap_remove_all (m, &k1));
  for (j = 0; j < 1024; j++)
    CHECK (GNUNET_OK ==
           GNUNET_CONTAINER_multipeermap_put (m, &k1, "v2",
                                              GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
  iter = GNUNET_CONTAINER_multipeermap_iterator_create (m);
  for (j = 0; j < GNUNET_CONTAINER_multipeermap_size (m); j++)
    CHECK (GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter, NULL, NULL));
  CHECK (GNUNET_NO == GNUNET_CONTAINER_multipeermap_iterator_next (iter, NULL, NULL));
  GNUNET_free (iter);

  GNUNET_CONTAINER_multipeermap_destroy (m);
  return 0;
}
static int
check ()
{
#define MAX_TESTVAL 1024
  char *ptrs[MAX_TESTVAL];
  int i;
  int j;
  int k;
  unsigned int ui;

  /* GNUNET_malloc/GNUNET_free test */
  k = 352;                      /* random start value */
  for (i = 1; i < MAX_TESTVAL; i++)
  {
    ptrs[i] = GNUNET_malloc (i);
    for (j = 0; j < i; j++)
      ptrs[i][j] = k++;
  }

  for (i = MAX_TESTVAL - 1; i >= 1; i--)
  {
    for (j = i - 1; j >= 0; j--)
      if (ptrs[i][j] != (char) --k)
        return 1;
    GNUNET_free (ptrs[i]);
  }

  /* GNUNET_free_non_null test */
  GNUNET_free_non_null (NULL);
  GNUNET_free_non_null (GNUNET_malloc (4));

  /* GNUNET_strdup tests */
  ptrs[0] = GNUNET_strdup ("bar");
  if (0 != strcmp (ptrs[0], "bar"))
    return 3;
  /* now realloc */
  ptrs[0] = GNUNET_realloc (ptrs[0], 12);
  strcpy (ptrs[0], "Hello World");

  GNUNET_free (ptrs[0]);
  GNUNET_asprintf (&ptrs[0], "%s %s", "Hello", "World");
  GNUNET_assert (strlen (ptrs[0]) == 11);
  GNUNET_free (ptrs[0]);

  /* GNUNET_array_grow tests */
  ptrs[0] = NULL;
  ui = 0;
  GNUNET_array_grow (ptrs[0], ui, 42);
  if (ui != 42)
    return 4;
  GNUNET_array_grow (ptrs[0], ui, 22);
  if (ui != 22)
    return 5;
  for (j = 0; j < 22; j++)
    ptrs[0][j] = j;
  GNUNET_array_grow (ptrs[0], ui, 32);
  for (j = 0; j < 22; j++)
    if (ptrs[0][j] != j)
      return 6;
  for (j = 22; j < 32; j++)
    if (ptrs[0][j] != 0)
      return 7;
  GNUNET_array_grow (ptrs[0], ui, 0);
  if (i != 0)
    return 8;
  if (ptrs[0] != NULL)
    return 9;


  return 0;
}
Exemple #30
0
static void
run (void *cls,
     const struct GNUNET_CONFIGURATION_Handle *cfg,
     struct GNUNET_TESTING_Peer *peer)
{
  enum MHD_FLAG flags;
  struct GNUNET_CRYPTO_EcdsaPrivateKey *host_key;
  struct GNUNET_GNSRECORD_Data rd;
  char *zone_keyfile;

  namestore = GNUNET_NAMESTORE_connect (cfg);
  GNUNET_assert (NULL != namestore);
  flags = MHD_USE_DEBUG;
  mhd = MHD_start_daemon (flags,
			  PORT,
			  NULL, NULL,
			  &mhd_ahc, NULL,
			  MHD_OPTION_END);
  GNUNET_assert (NULL != mhd);
  mhd_main ();

  tmp_cfgfile = GNUNET_DISK_mktemp ("test_gns_proxy_tmp.conf");
  if (NULL == tmp_cfgfile)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                "Failed to create tmp cfg!\n");
    do_shutdown ();
    return;
  }

  if (GNUNET_OK != GNUNET_CONFIGURATION_write ((struct GNUNET_CONFIGURATION_Handle *)cfg,
                              tmp_cfgfile))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                "Failed to write tmp cfg\n");
    do_shutdown ();
    return;
  }

  proxy_proc = GNUNET_OS_start_process (GNUNET_NO,
                                        GNUNET_OS_INHERIT_STD_ALL,
                                        NULL,
                                        NULL,
                                        NULL,
                                        "gnunet-gns-proxy",
                                        "gnunet-gns-proxy",
                                        "-c", tmp_cfgfile, NULL);

  if (NULL == proxy_proc)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                "Unable to start proxy\n");
    do_shutdown ();
    return;
  }

  if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns",
                                                            "ZONEKEY",
                                                            &zone_keyfile))
  {
    GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to get key from cfg\n");
    return;
  }

  host_key = GNUNET_CRYPTO_ecdsa_key_create_from_file (zone_keyfile);
  rd.expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
  GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_string_to_value (GNUNET_DNSPARSER_TYPE_A,
                                                               "127.0.0.1",
                                                               (void**)&rd.data,
                                                               &rd.data_size));
  rd.record_type = GNUNET_DNSPARSER_TYPE_A;

  GNUNET_NAMESTORE_record_create (namestore,
                                  host_key,
                                  "www",
                                  &rd,
                                  &commence_testing,
                                  NULL);

  GNUNET_free ((void**)rd.data);
  GNUNET_free (zone_keyfile);
  GNUNET_free (host_key);
}