#include "mesh_path.h"
#include "gnunet-service-mesh_dht.h"
#include "gnunet-service-mesh_peer.h"
+#include "gnunet-service-mesh_hello.h"
#define LOG(level, ...) GNUNET_log_from (level,"mesh-dht",__VA_ARGS__)
/** Provided closure. */
void *cls;
+
+ /** Peer ID searched for */
+ GNUNET_PEER_Id peer_id;
};
*/
extern struct GNUNET_STATISTICS_Handle *stats;
+/**
+ * Own ID (short value).
+ */
+extern GNUNET_PEER_Id myid;
+
+/**
+ * Own ID (full value).
+ */
+extern struct GNUNET_PeerIdentity my_full_id;
+
/**
* Handle to use DHT.
*/
static GNUNET_SCHEDULER_TaskIdentifier announce_id_task;
/**
- * Own ID (short value).
- */
-static GNUNET_PEER_Id short_id;
-
-/**
- * Own ID (full value).
- */
-static struct GNUNET_PeerIdentity *full_id;
-
-/**
- * Own private key.
+ * GET requests to stop on shutdown.
*/
-static struct GNUNET_CRYPTO_EccPrivateKey *private_key;
-
+static struct GNUNET_CONTAINER_MultiHashMap32 *get_requests;
/******************************************************************************/
/******************************** STATIC ***********************************/
* to obtain a local peer -> destination path and interning the peer ids.
*
* @return Newly allocated and created path
+ *
+ * FIXME refactor and use build_path_from_peer_ids
*/
static struct MeshPeerPath *
path_build_from_dht (const struct GNUNET_PeerIdentity *get_path,
size_t size, const void *data)
{
struct GMD_search_handle *h = cls;
+ struct GNUNET_HELLO_Message *hello;
struct MeshPeerPath *p;
+ struct MeshPeer *peer;
+ char *s;
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Got results!\n");
p = path_build_from_dht (get_path, get_path_length,
put_path, put_path_length);
+ s = path_2s (p);
+ LOG (GNUNET_ERROR_TYPE_INFO, "Got path from DHT: %s\n", s);
+ GNUNET_free_non_null (s);
+ peer = GMP_get_short (p->peers[p->length - 1]);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Got HELLO for %s\n", GMP_2s (peer));
h->callback (h->cls, p);
path_destroy (p);
+ hello = (struct GNUNET_HELLO_Message *) data;
+ GMP_set_hello (peer, hello);
+ GMP_try_connect (peer);
return;
}
static void
announce_id (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
- struct PBlock block;
struct GNUNET_HashCode phash;
+ const struct GNUNET_HELLO_Message *hello;
+ size_t size;
+ struct GNUNET_TIME_Absolute expiration;
+ struct GNUNET_TIME_Relative retry_time;
if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
{
announce_id_task = GNUNET_SCHEDULER_NO_TASK;
return;
}
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Announce ID\n");
/* TODO
* - Set data expiration in function of X
* - Adapt X to churn
*/
- block.id = *full_id;
- GNUNET_CRYPTO_hash (full_id, sizeof (struct GNUNET_PeerIdentity), &phash);
+ hello = GMH_get_mine ();
+ if (NULL == hello || (size = GNUNET_HELLO_size (hello)) == 0)
+ {
+ /* 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");
+ return;
+ }
+ 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);
+ 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_MESH_PEER, /* Block type */
- sizeof (block), /* Size of the data */
- (const char *) &block, /* Data itself */
- GNUNET_TIME_UNIT_FOREVER_ABS, /* Data expiration */
- GNUNET_TIME_UNIT_FOREVER_REL, /* Retry time */
+ 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);
}
+/**
+ * Iterator over hash map entries and stop GET requests before disconnecting
+ * from the DHT.
+ *
+ * @param cls Closure (unused)
+ * @param key Current peer ID.
+ * @param value Value in the hash map (GMD_search_handle).
+ *
+ * @return #GNUNET_YES, we should continue to iterate,
+ */
+int
+stop_get (void *cls,
+ uint32_t key,
+ void *value)
+{
+ struct GMD_search_handle *h = value;
+
+ GMD_search_stop (h);
+ return GNUNET_YES;
+}
+
/******************************************************************************/
/******************************** API ***********************************/
* Initialize the DHT subsystem.
*
* @param c Configuration.
- * @param peer_id Local peer ID (must remain valid during all execution time).
*/
void
-GMD_init (const struct GNUNET_CONFIGURATION_Handle *c,
- struct GNUNET_PeerIdentity *peer_id)
+GMD_init (const struct GNUNET_CONFIGURATION_Handle *c)
{
- full_id = peer_id;
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "init\n");
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_number (c, "MESH", "DHT_REPLICATION_LEVEL",
&dht_replication_level))
{
- LOG_config_invalid (GNUNET_ERROR_TYPE_WARNING,
+ GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
"MESH", "DHT_REPLICATION_LEVEL", "USING DEFAULT");
dht_replication_level = 3;
}
GNUNET_CONFIGURATION_get_value_time (c, "MESH", "ID_ANNOUNCE_TIME",
&id_announce_time))
{
- LOG_config_invalid (GNUNET_ERROR_TYPE_ERROR,
+ GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
"MESH", "ID_ANNOUNCE_TIME", "MISSING");
GNUNET_SCHEDULER_shutdown ();
return;
}
announce_id_task = GNUNET_SCHEDULER_add_now (&announce_id, NULL);
+ get_requests = GNUNET_CONTAINER_multihashmap32_create (32);
}
* Shut down the DHT subsystem.
*/
void
-GMD_shutdown(void )
+GMD_shutdown (void)
{
+ GNUNET_CONTAINER_multihashmap32_iterate (get_requests, &stop_get, NULL);
+ GNUNET_CONTAINER_multihashmap32_destroy (get_requests);
if (dht_handle != NULL)
{
GNUNET_DHT_disconnect (dht_handle);
LOG (GNUNET_ERROR_TYPE_DEBUG,
" Starting DHT GET for peer %s\n", GNUNET_i2s (peer_id));
- GNUNET_CRYPTO_hash (peer_id, sizeof (struct GNUNET_PeerIdentity), &phash);
+ memset (&phash, 0, sizeof (phash));
+ memcpy (&phash, peer_id, sizeof (*peer_id));
h = GNUNET_new (struct GMD_search_handle);
+ h->peer_id = GNUNET_PEER_intern (peer_id);
+ h->callback = callback;
h->cls = cls;
h->dhtget = GNUNET_DHT_get_start (dht_handle, /* handle */
- GNUNET_BLOCK_TYPE_MESH_PEER, /* type */
+ GNUNET_BLOCK_TYPE_DHT_HELLO, /* type */
&phash, /* key to search */
dht_replication_level, /* replication level */
GNUNET_DHT_RO_RECORD_ROUTE |
NULL, /* xquery */
0, /* xquery bits */
&dht_get_id_handler, h);
+ GNUNET_CONTAINER_multihashmap32_put (get_requests, h->peer_id, h,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
return h;
}
void
GMD_search_stop (struct GMD_search_handle *h)
{
+ GNUNET_break (GNUNET_OK ==
+ GNUNET_CONTAINER_multihashmap32_remove (get_requests,
+ h->peer_id, h));
GNUNET_DHT_get_stop (h->dhtget);
GNUNET_free (h);
-}
\ No newline at end of file
+}