/*
This file is part of GNUnet.
- (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
You should have received a copy of the GNU General Public License
along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
*/
/**
* Handle for DHT searches.
*/
-struct GMD_search_handle
+struct GCD_search_handle
{
/** DHT_GET handle. */
struct GNUNET_DHT_GetHandle *dhtget;
/** Provided callback to call when a path is found. */
- GMD_search_callback callback;
+ GCD_search_callback callback;
/** Provided closure. */
void *cls;
/**
* Task to periodically announce itself in the network.
*/
-static GNUNET_SCHEDULER_TaskIdentifier announce_id_task;
+static struct GNUNET_SCHEDULER_Task * announce_id_task;
/**
* GET requests to stop on shutdown.
const struct GNUNET_PeerIdentity *put_path,
unsigned int put_path_length)
{
+ size_t size = get_path_length + put_path_length + 1;
+ struct GNUNET_PeerIdentity peers[size];
+ const struct GNUNET_PeerIdentity *peer;
struct CadetPeerPath *p;
- GNUNET_PEER_Id id;
+ unsigned int own_pos;
int i;
- p = path_new (1);
- p->peers[0] = myid;
- GNUNET_PEER_change_rc (myid, 1);
- i = get_path_length;
- LOG (GNUNET_ERROR_TYPE_DEBUG, " GET has %d hops.\n", i);
- for (i--; i >= 0; i--)
+ peers[0] = my_full_id;
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " GET has %d hops.\n", get_path_length);
+ for (i = 0 ; i < get_path_length; i++)
{
- id = GNUNET_PEER_intern (&get_path[i]);
- if (p->length > 0 && id == p->peers[p->length - 1])
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG, " Optimizing 1 hop out.\n");
- GNUNET_PEER_change_rc (id, -1);
- }
- else
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG, " Adding from GET: %s.\n",
- GNUNET_i2s (&get_path[i]));
- p->length++;
- p->peers = GNUNET_realloc (p->peers, sizeof (GNUNET_PEER_Id) * p->length);
- p->peers[p->length - 1] = id;
- }
+ peer = &get_path[get_path_length - i - 1];
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " From GET: %s\n", GNUNET_i2s (peer));
+ peers[i + 1] = *peer;
}
- i = put_path_length;
- LOG (GNUNET_ERROR_TYPE_DEBUG, " PUT has %d hops.\n", i);
- for (i--; i >= 0; i--)
+ for (i = 0 ; i < put_path_length; i++)
{
- id = GNUNET_PEER_intern (&put_path[i]);
- if (id == myid)
- {
- /* PUT path went through us, so discard the path up until now and start
- * from here to get a much shorter (and loop-free) path.
- */
- path_destroy (p);
- p = path_new (0);
- }
- if (p->length > 0 && id == p->peers[p->length - 1])
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG, " Optimizing 1 hop out.\n");
- GNUNET_PEER_change_rc (id, -1);
- }
- else
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG, " Adding from PUT: %s.\n",
- GNUNET_i2s (&put_path[i]));
- p->length++;
- p->peers = GNUNET_realloc (p->peers, sizeof (GNUNET_PEER_Id) * p->length);
- p->peers[p->length - 1] = id;
- }
+ peer = &put_path[put_path_length - i - 1];
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " From PUT: %s\n", GNUNET_i2s (peer));
+ peers[i + get_path_length + 1] = *peer;
}
-#if CADET_DEBUG
- if (get_path_length > 0)
- LOG (GNUNET_ERROR_TYPE_DEBUG, " (first of GET: %s)\n",
- GNUNET_i2s (&get_path[0]));
- if (put_path_length > 0)
- LOG (GNUNET_ERROR_TYPE_DEBUG, " (first of PUT: %s)\n",
- GNUNET_i2s (&put_path[0]));
- LOG (GNUNET_ERROR_TYPE_DEBUG, " In total: %d hops\n",
- p->length);
- for (i = 0; i < p->length; i++)
- {
- struct GNUNET_PeerIdentity peer_id;
-
- GNUNET_PEER_resolve (p->peers[i], &peer_id);
- LOG (GNUNET_ERROR_TYPE_DEBUG, " %u: %s\n", p->peers[i],
- GNUNET_i2s (&peer_id));
- }
-#endif
+ p = path_build_from_peer_ids (peers, size, myid, &own_pos);
return p;
}
* @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
unsigned int put_path_length, enum GNUNET_BLOCK_Type type,
size_t size, const void *data)
{
- struct GMD_search_handle *h = cls;
+ struct GCD_search_handle *h = cls;
struct GNUNET_HELLO_Message *hello;
struct CadetPeerPath *p;
struct CadetPeer *peer;
p = path_build_from_dht (get_path, get_path_length,
put_path, put_path_length);
+ if (NULL == p)
+ {
+ GNUNET_break_op (0);
+ return;
+ }
+
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 = GMP_get_short (p->peers[p->length - 1]);
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Got HELLO for %s\n", GMP_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;
- GMP_set_hello (peer, hello);
- GMP_try_connect (peer);
- return;
+ GCP_set_hello (peer, hello);
+ GCP_try_connect (peer);
}
* 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;
- if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
- {
- announce_id_task = GNUNET_SCHEDULER_NO_TASK;
- 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 = GMH_get_mine ();
+ hello = GCH_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");
+ GNUNET_STATISTICS_update (stats, "# DHT announce skipped (no hello)",
+ 1, GNUNET_NO);
+
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);
+ GNUNET_STATISTICS_update (stats, "# DHT announce",
+ 1, GNUNET_NO);
memset (&phash, 0, sizeof (phash));
- memcpy (&phash, &my_full_id, sizeof (my_full_id));
+ 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 */
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 =
*
* @param cls Closure (unused)
* @param key Current peer ID.
- * @param value Value in the hash map (GMD_search_handle).
+ * @param value Value in the hash map (GCD_search_handle).
*
* @return #GNUNET_YES, we should continue to iterate,
*/
uint32_t key,
void *value)
{
- struct GMD_search_handle *h = value;
+ struct GCD_search_handle *h = value;
- GMD_search_stop (h);
+ GCD_search_stop (h);
return GNUNET_YES;
}
* @param c Configuration.
*/
void
-GMD_init (const struct GNUNET_CONFIGURATION_Handle *c)
+GCD_init (const struct GNUNET_CONFIGURATION_Handle *c)
{
LOG (GNUNET_ERROR_TYPE_DEBUG, "init\n");
if (GNUNET_OK !=
* Shut down the DHT subsystem.
*/
void
-GMD_shutdown (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_DHT_disconnect (dht_handle);
dht_handle = NULL;
}
- if (GNUNET_SCHEDULER_NO_TASK != announce_id_task)
+ if (NULL != announce_id_task)
{
GNUNET_SCHEDULER_cancel (announce_id_task);
- announce_id_task = GNUNET_SCHEDULER_NO_TASK;
+ announce_id_task = NULL;
}
}
-struct GMD_search_handle *
-GMD_search (const struct GNUNET_PeerIdentity *peer_id,
- GMD_search_callback callback, void *cls)
+struct GCD_search_handle *
+GCD_search (const struct GNUNET_PeerIdentity *peer_id,
+ GCD_search_callback callback, void *cls)
{
struct GNUNET_HashCode phash;
- struct GMD_search_handle *h;
+ struct GCD_search_handle *h;
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- " Starting DHT GET for peer %s\n", GNUNET_i2s (peer_id));
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting DHT GET for peer %s\n",
+ 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));
- h = GNUNET_new (struct GMD_search_handle);
+ 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;
h->cls = cls;
return h;
}
+
void
-GMD_search_stop (struct GMD_search_handle *h)
+GCD_search_stop (struct GCD_search_handle *h)
{
GNUNET_break (GNUNET_OK ==
GNUNET_CONTAINER_multihashmap32_remove (get_requests,