/*
This file is part of GNUnet.
- Copyright (C) 2013 Christian Grothoff (and other contributing authors)
+ Copyright (C) 2013 GNUnet e.V.
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
*/
struct GCD_search_handle
{
- /** DHT_GET handle. */
+ /**
+ * DHT_GET handle.
+ */
struct GNUNET_DHT_GetHandle *dhtget;
- /** Provided callback to call when a path is found. */
+ /**
+ * Provided callback to call when a path is found.
+ */
GCD_search_callback callback;
- /** Provided closure. */
+ /**
+ * Provided closure.
+ */
void *cls;
- /** Peer ID searched for */
+ /**
+ * Peer ID searched for
+ */
GNUNET_PEER_Id peer_id;
};
*/
static struct GNUNET_SCHEDULER_Task * announce_id_task;
+/**
+ * Delay for the next ID announce.
+ */
+static struct GNUNET_TIME_Relative announce_delay;
+
/**
* GET requests to stop on shutdown.
*/
* @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 get_path_length lenght of @a get_path
* @param put_path path of the put request
- * @param put_path_length length of the put_path
+ * @param put_path_length length of the @a put_path
* @param type type of the result
* @param size number of bytes in data
* @param data pointer to the result data
}
s = path_2s (p);
- LOG (GNUNET_ERROR_TYPE_INFO, "Got path from DHT: %s\n", s);
+ LOG (GNUNET_ERROR_TYPE_INFO,
+ "Got path from DHT: %s\n",
+ s);
GNUNET_free_non_null (s);
- peer = GCP_get_short (p->peers[p->length - 1]);
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Got HELLO for %s\n", GCP_2s (peer));
+
+ peer = GCP_get_short (p->peers[p->length - 1], GNUNET_YES);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Got HELLO for %s\n",
+ GCP_2s (peer));
h->callback (h->cls, p);
path_destroy (p);
hello = (struct GNUNET_HELLO_Message *) data;
* Periodically announce self id in the DHT
*
* @param cls closure
- * @param tc task context
*/
static void
-announce_id (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+announce_id (void *cls)
{
struct GNUNET_HashCode phash;
const struct GNUNET_HELLO_Message *hello;
size_t size;
struct GNUNET_TIME_Absolute expiration;
- struct GNUNET_TIME_Relative retry_time;
+ struct GNUNET_TIME_Relative next_put;
- if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
- {
- announce_id_task = NULL;
- return;
- }
+ announce_id_task = NULL;
LOG (GNUNET_ERROR_TYPE_DEBUG, "Announce ID\n");
- /* TODO
- * - Set data expiration in function of X
- * - Adapt X to churn
- */
hello = GCH_get_mine ();
- if (NULL == hello || (size = GNUNET_HELLO_size (hello)) == 0)
+ size = (NULL != hello) ? GNUNET_HELLO_size (hello) : 0;
+ if ( (NULL == hello) || (0 == size) )
{
- /* Peerinfo gave us no hello yet, try again in a second. */
- announce_id_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
- &announce_id, cls);
- LOG (GNUNET_ERROR_TYPE_DEBUG, " no hello, waiting!\n");
- GNUNET_STATISTICS_update (stats, "# DHT announce skipped (no hello)",
- 1, GNUNET_NO);
-
- return;
+ /* Peerinfo gave us no hello yet, try again soon. */
+ LOG (GNUNET_ERROR_TYPE_INFO,
+ " no hello, waiting!\n");
+ GNUNET_STATISTICS_update (stats,
+ "# DHT announce skipped (no hello)",
+ 1,
+ GNUNET_NO);
+ expiration = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
+ announce_delay);
+ announce_delay = GNUNET_TIME_STD_BACKOFF (announce_delay);
+ }
+ else
+ {
+ expiration = GNUNET_HELLO_get_last_expiration (hello);
+ announce_delay = GNUNET_TIME_UNIT_SECONDS;
}
- expiration = GNUNET_HELLO_get_last_expiration (hello);
- retry_time = GNUNET_TIME_absolute_get_remaining (expiration);
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Hello %p size: %u\n", hello, size);
- GNUNET_STATISTICS_update (stats, "# DHT announce",
- 1, GNUNET_NO);
- memset (&phash, 0, sizeof (phash));
- memcpy (&phash, &my_full_id, sizeof (my_full_id));
- GNUNET_DHT_put (dht_handle, /* DHT handle */
- &phash, /* Key to use */
- dht_replication_level, /* Replication level */
- GNUNET_DHT_RO_RECORD_ROUTE
- | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, /* DHT options */
- GNUNET_BLOCK_TYPE_DHT_HELLO, /* Block type */
- size, /* Size of the data */
- (const char *) hello, /* Data itself */
- expiration, /* Data expiration */
- retry_time, /* Retry time */
- NULL, /* Continuation */
- NULL); /* Continuation closure */
- announce_id_task =
- GNUNET_SCHEDULER_add_delayed (id_announce_time, &announce_id, cls);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Hello %p size: %u\n",
+ hello,
+ size);
+ if (NULL != hello)
+ {
+ GNUNET_STATISTICS_update (stats,
+ "# DHT announce",
+ 1, GNUNET_NO);
+ memset (&phash,
+ 0,
+ sizeof (phash));
+ GNUNET_memcpy (&phash,
+ &my_full_id,
+ sizeof (my_full_id));
+ GNUNET_DHT_put (dht_handle, /* DHT handle */
+ &phash, /* Key to use */
+ dht_replication_level, /* Replication level */
+ GNUNET_DHT_RO_RECORD_ROUTE
+ | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, /* DHT options */
+ GNUNET_BLOCK_TYPE_DHT_HELLO, /* Block type */
+ size, /* Size of the data */
+ (const char *) hello, /* Data itself */
+ expiration, /* Data expiration */
+ NULL, /* Continuation */
+ NULL); /* Continuation closure */
+ }
+ /* Call again in id_announce_time, unless HELLO expires first,
+ * but wait at least 1s. */
+ next_put = GNUNET_TIME_absolute_get_remaining (expiration);
+ next_put = GNUNET_TIME_relative_min (next_put,
+ id_announce_time);
+ next_put = GNUNET_TIME_relative_max (next_put,
+ GNUNET_TIME_UNIT_SECONDS);
+ announce_id_task = GNUNET_SCHEDULER_add_delayed (next_put,
+ &announce_id,
+ cls);
}
/**
{
LOG (GNUNET_ERROR_TYPE_DEBUG, "init\n");
if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_number (c, "CADET", "DHT_REPLICATION_LEVEL",
+ GNUNET_CONFIGURATION_get_value_number (c, "CADET",
+ "DHT_REPLICATION_LEVEL",
&dht_replication_level))
{
- GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
- "CADET", "DHT_REPLICATION_LEVEL", "USING DEFAULT");
+ GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING, "CADET",
+ "DHT_REPLICATION_LEVEL", "USING DEFAULT");
dht_replication_level = 3;
}
GNUNET_CONFIGURATION_get_value_time (c, "CADET", "ID_ANNOUNCE_TIME",
&id_announce_time))
{
- GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
- "CADET", "ID_ANNOUNCE_TIME", "MISSING");
+ GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, "CADET",
+ "ID_ANNOUNCE_TIME", "MISSING");
GNUNET_SCHEDULER_shutdown ();
return;
}
GNUNET_break (0);
}
+ announce_delay = GNUNET_TIME_UNIT_SECONDS;
announce_id_task = GNUNET_SCHEDULER_add_now (&announce_id, NULL);
get_requests = GNUNET_CONTAINER_multihashmap32_create (32);
}
void
GCD_shutdown (void)
{
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down DHT\n");
GNUNET_CONTAINER_multihashmap32_iterate (get_requests, &stop_get, NULL);
GNUNET_CONTAINER_multihashmap32_destroy (get_requests);
if (dht_handle != NULL)
GNUNET_i2s (peer_id));
GNUNET_STATISTICS_update (stats, "# DHT search", 1, GNUNET_NO);
memset (&phash, 0, sizeof (phash));
- memcpy (&phash, peer_id, sizeof (*peer_id));
+ GNUNET_memcpy (&phash, peer_id, sizeof (*peer_id));
h = GNUNET_new (struct GCD_search_handle);
h->peer_id = GNUNET_PEER_intern (peer_id);
h->callback = callback;
GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
NULL, /* xquery */
0, /* xquery bits */
- &dht_get_id_handler, h);
- GNUNET_CONTAINER_multihashmap32_put (get_requests, h->peer_id, h,
+ &dht_get_id_handler,
+ h);
+ GNUNET_CONTAINER_multihashmap32_put (get_requests,
+ h->peer_id,
+ h,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
return h;
}