aboutsummaryrefslogtreecommitdiff
path: root/src/dht/gnunet-service-dht_neighbours.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dht/gnunet-service-dht_neighbours.c')
-rw-r--r--src/dht/gnunet-service-dht_neighbours.c151
1 files changed, 118 insertions, 33 deletions
diff --git a/src/dht/gnunet-service-dht_neighbours.c b/src/dht/gnunet-service-dht_neighbours.c
index 083b499..4872b58 100644
--- a/src/dht/gnunet-service-dht_neighbours.c
+++ b/src/dht/gnunet-service-dht_neighbours.c
@@ -52,7 +52,7 @@
/**
* How many buckets will we allow total.
*/
-#define MAX_BUCKETS sizeof (GNUNET_HashCode) * 8
+#define MAX_BUCKETS sizeof (struct GNUNET_HashCode) * 8
/**
* What is the maximum number of peers in a given bucket.
@@ -70,6 +70,11 @@
#define MAXIMUM_REPLICATION_LEVEL 16
/**
+ * Maximum allowed number of pending messages per peer.
+ */
+#define MAXIMUM_PENDING_PER_PEER 64
+
+/**
* How often to update our preference levels for peers in our routing tables.
*/
#define DHT_DEFAULT_PREFERENCE_INTERVAL GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2)
@@ -89,6 +94,17 @@
*/
#define GET_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2)
+/**
+ * Should routing details be logged to stderr (for debugging)?
+ */
+#define LOG_ROUTE_DETAILS_STDERR GNUNET_NO
+
+
+/**
+ * Hello address expiration
+ */
+extern struct GNUNET_TIME_Relative hello_expiration;
+
GNUNET_NETWORK_STRUCT_BEGIN
@@ -140,7 +156,7 @@ struct PeerPutMessage
/**
* The key we are storing under.
*/
- GNUNET_HashCode key;
+ struct GNUNET_HashCode key;
/* put path (if tracked) */
@@ -182,7 +198,7 @@ struct PeerResultMessage
/**
* The key of the corresponding GET request.
*/
- GNUNET_HashCode key;
+ struct GNUNET_HashCode key;
/* put path (if tracked) */
@@ -241,7 +257,7 @@ struct PeerGetMessage
/**
* The key we are looking for.
*/
- GNUNET_HashCode key;
+ struct GNUNET_HashCode key;
/* xquery */
@@ -301,8 +317,7 @@ struct PeerInfo
struct PeerInfo *prev;
/**
- * Count of outstanding messages for peer. FIXME: NEEDED?
- * FIXME: bound queue size!?
+ * Count of outstanding messages for peer.
*/
unsigned int pending_count;
@@ -380,6 +395,11 @@ static unsigned int closest_bucket;
static unsigned int newly_found_peers;
/**
+ * Option for testing that disables the 'connect' function of the DHT.
+ */
+static int disable_try_connect;
+
+/**
* The buckets. Array of size MAX_BUCKET_SIZE. Offset 0 means 0 bits matching.
*/
static struct PeerBucket k_buckets[MAX_BUCKETS];
@@ -424,7 +444,7 @@ static struct GNUNET_ATS_PerformanceHandle *atsAPI;
* on error (same hashcode)
*/
static int
-find_bucket (const GNUNET_HashCode * hc)
+find_bucket (const struct GNUNET_HashCode * hc)
{
unsigned int bits;
@@ -518,10 +538,10 @@ struct BloomConstructorContext
* @return GNUNET_YES (we should continue to iterate)
*/
static int
-add_known_to_bloom (void *cls, const GNUNET_HashCode * key, void *value)
+add_known_to_bloom (void *cls, const struct GNUNET_HashCode * key, void *value)
{
struct BloomConstructorContext *ctx = cls;
- GNUNET_HashCode mh;
+ struct GNUNET_HashCode mh;
GNUNET_BLOCK_mingle_hash (key, ctx->bf_mutator, &mh);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -807,7 +827,7 @@ process_peer_queue (struct PeerInfo *peer)
return;
GNUNET_STATISTICS_update (GDS_stats,
gettext_noop
- ("# Bytes of bandwdith requested from core"),
+ ("# Bytes of bandwidth requested from core"),
ntohs (pending->msg->size), GNUNET_NO);
peer->th =
GNUNET_CORE_notify_transmit_ready (coreAPI, GNUNET_YES,
@@ -874,7 +894,7 @@ get_forward_count (uint32_t hop_count, uint32_t target_replication)
* the two hash codes increases
*/
static unsigned int
-get_distance (const GNUNET_HashCode * target, const GNUNET_HashCode * have)
+get_distance (const struct GNUNET_HashCode * target, const struct GNUNET_HashCode * have)
{
unsigned int bucket;
unsigned int msb;
@@ -911,7 +931,7 @@ get_distance (const GNUNET_HashCode * target, const GNUNET_HashCode * have)
* mismatching bit at 'bucket' */
lsb = 0;
for (i = bucket + 1;
- (i < sizeof (GNUNET_HashCode) * 8) && (i < bucket + 1 + 32 - 9); i++)
+ (i < sizeof (struct GNUNET_HashCode) * 8) && (i < bucket + 1 + 32 - 9); i++)
{
if (GNUNET_CRYPTO_hash_get_bit (target, i) !=
GNUNET_CRYPTO_hash_get_bit (have, i))
@@ -934,7 +954,7 @@ get_distance (const GNUNET_HashCode * target, const GNUNET_HashCode * have)
* GNUNET_NO otherwise.
*/
static int
-am_closest_peer (const GNUNET_HashCode * key,
+am_closest_peer (const struct GNUNET_HashCode * key,
const struct GNUNET_CONTAINER_BloomFilter *bloom)
{
int bits;
@@ -943,7 +963,7 @@ am_closest_peer (const GNUNET_HashCode * key,
int count;
struct PeerInfo *pos;
- if (0 == memcmp (&my_identity.hashPubKey, key, sizeof (GNUNET_HashCode)))
+ if (0 == memcmp (&my_identity.hashPubKey, key, sizeof (struct GNUNET_HashCode)))
return GNUNET_YES;
bucket_num = find_bucket (key);
GNUNET_assert (bucket_num >= 0);
@@ -989,7 +1009,7 @@ am_closest_peer (const GNUNET_HashCode * key,
* @return Peer to route to, or NULL on error
*/
static struct PeerInfo *
-select_peer (const GNUNET_HashCode * key,
+select_peer (const struct GNUNET_HashCode * key,
const struct GNUNET_CONTAINER_BloomFilter *bloom, uint32_t hops)
{
unsigned int bc;
@@ -1081,19 +1101,16 @@ select_peer (const GNUNET_HashCode * key,
count = 0;
for (bc = 0; bc <= closest_bucket; bc++)
{
- pos = k_buckets[bc].head;
- while ((pos != NULL) && (count < bucket_size))
+ for (pos = k_buckets[bc].head; ((pos != NULL) && (count < bucket_size)); pos = pos->next)
{
if ((bloom != NULL) &&
(GNUNET_YES ==
GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey)))
{
- pos = pos->next;
continue; /* Ignore bloomfiltered peers */
}
if (0 == selected--)
return pos;
- pos = pos->next;
}
}
GNUNET_break (0);
@@ -1115,7 +1132,7 @@ select_peer (const GNUNET_HashCode * key,
* @return number of peers returned in 'targets'.
*/
static unsigned int
-get_target_peers (const GNUNET_HashCode * key,
+get_target_peers (const struct GNUNET_HashCode *key,
struct GNUNET_CONTAINER_BloomFilter *bloom,
uint32_t hop_count, uint32_t target_replication,
struct PeerInfo ***targets)
@@ -1126,7 +1143,7 @@ get_target_peers (const GNUNET_HashCode * key,
struct PeerInfo *nxt;
GNUNET_assert (NULL != bloom);
- ret = get_forward_count (hop_count, target_replication);
+ ret = get_forward_count (hop_count, target_replication);
if (ret == 0)
{
*targets = NULL;
@@ -1155,6 +1172,11 @@ get_target_peers (const GNUNET_HashCode * key,
return 0;
}
*targets = rtargets;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Forwarding query `%s' to %u peers (goal was %u peers)\n",
+ GNUNET_h2s (key),
+ off,
+ ret);
return off;
}
@@ -1185,7 +1207,7 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
struct GNUNET_TIME_Absolute expiration_time,
uint32_t hop_count,
struct GNUNET_CONTAINER_BloomFilter *bf,
- const GNUNET_HashCode * key,
+ const struct GNUNET_HashCode * key,
unsigned int put_path_length,
struct GNUNET_PeerIdentity *put_path,
const void *data, size_t data_size)
@@ -1238,6 +1260,12 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
for (i = 0; i < target_count; i++)
{
target = targets[i];
+ if (target->pending_count >= MAXIMUM_PENDING_PER_PEER)
+ {
+ GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
+ 1, GNUNET_NO);
+ continue; /* skip */
+ }
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Routing PUT for %s after %u hops to %s\n", GNUNET_h2s (key),
(unsigned int) hop_count, GNUNET_i2s (&target->id));
@@ -1295,7 +1323,7 @@ void
GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type,
enum GNUNET_DHT_RouteOption options,
uint32_t desired_replication_level,
- uint32_t hop_count, const GNUNET_HashCode * key,
+ uint32_t hop_count, const struct GNUNET_HashCode * key,
const void *xquery, size_t xquery_size,
const struct GNUNET_CONTAINER_BloomFilter *reply_bf,
uint32_t reply_bf_mutator,
@@ -1345,6 +1373,12 @@ GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type,
for (i = 0; i < target_count; i++)
{
target = targets[i];
+ if (target->pending_count >= MAXIMUM_PENDING_PER_PEER)
+ {
+ GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
+ 1, GNUNET_NO);
+ continue; /* skip */
+ }
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Routing GET for %s after %u hops to %s\n", GNUNET_h2s (key),
(unsigned int) hop_count, GNUNET_i2s (&target->id));
@@ -1405,7 +1439,7 @@ void
GDS_NEIGHBOURS_handle_reply (const struct GNUNET_PeerIdentity *target,
enum GNUNET_BLOCK_Type type,
struct GNUNET_TIME_Absolute expiration_time,
- const GNUNET_HashCode * key,
+ const struct GNUNET_HashCode * key,
unsigned int put_path_length,
const struct GNUNET_PeerIdentity *put_path,
unsigned int get_path_length,
@@ -1438,6 +1472,14 @@ GDS_NEIGHBOURS_handle_reply (const struct GNUNET_PeerIdentity *target,
/* peer disconnected in the meantime, drop reply */
return;
}
+ if (pi->pending_count >= MAXIMUM_PENDING_PER_PEER)
+ {
+ /* skip */
+ GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
+ 1, GNUNET_NO);
+ return;
+ }
+
GNUNET_STATISTICS_update (GDS_stats,
gettext_noop
("# RESULT messages queued for transmission"), 1,
@@ -1508,7 +1550,7 @@ handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer,
size_t payload_size;
enum GNUNET_DHT_RouteOption options;
struct GNUNET_CONTAINER_BloomFilter *bf;
- GNUNET_HashCode test_key;
+ struct GNUNET_HashCode test_key;
msize = ntohs (message->size);
if (msize < sizeof (struct PeerPutMessage))
@@ -1541,7 +1583,7 @@ handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer,
&test_key))
{
case GNUNET_YES:
- if (0 != memcmp (&test_key, &put->key, sizeof (GNUNET_HashCode)))
+ if (0 != memcmp (&test_key, &put->key, sizeof (struct GNUNET_HashCode)))
{
GNUNET_break_op (0);
return GNUNET_YES;
@@ -1556,6 +1598,19 @@ handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer,
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "PUT for `%s' from %s\n",
GNUNET_h2s (&put->key), GNUNET_i2s (peer));
+
+ if (LOG_ROUTE_DETAILS_STDERR)
+ {
+ char *tmp;
+
+ tmp = GNUNET_strdup (GNUNET_i2s (&my_identity));
+ fprintf (stderr, "XDHT PUT %s: %s(%u)<-%s\n",
+ GNUNET_h2s (&put->key), tmp, getpid (),
+ GNUNET_i2s (peer));
+ GNUNET_free (tmp);
+ }
+
+
bf = GNUNET_CONTAINER_bloomfilter_init (put->bloomfilter, DHT_BLOOM_SIZE,
GNUNET_CONSTANTS_BLOOMFILTER_K);
GNUNET_break_op (GNUNET_YES ==
@@ -1615,14 +1670,14 @@ handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer,
*/
static void
handle_find_peer (const struct GNUNET_PeerIdentity *sender,
- const GNUNET_HashCode * key,
+ const struct GNUNET_HashCode * key,
struct GNUNET_CONTAINER_BloomFilter *bf, uint32_t bf_mutator)
{
int bucket_idx;
struct PeerBucket *bucket;
struct PeerInfo *peer;
unsigned int choice;
- GNUNET_HashCode mhash;
+ struct GNUNET_HashCode mhash;
const struct GNUNET_HELLO_Message *hello;
/* first, check about our own HELLO */
@@ -1634,7 +1689,7 @@ handle_find_peer (const struct GNUNET_PeerIdentity *sender,
{
GDS_NEIGHBOURS_handle_reply (sender, GNUNET_BLOCK_TYPE_DHT_HELLO,
GNUNET_TIME_relative_to_absolute
- (GNUNET_CONSTANTS_HELLO_ADDRESS_EXPIRATION),
+ (hello_expiration),
key, 0, NULL, 0, NULL, GDS_my_hello,
GNUNET_HELLO_size ((const struct
GNUNET_HELLO_Message *)
@@ -1657,7 +1712,7 @@ handle_find_peer (const struct GNUNET_PeerIdentity *sender,
}
/* then, also consider sending a random HELLO from the closest bucket */
- if (0 == memcmp (&my_identity.hashPubKey, key, sizeof (GNUNET_HashCode)))
+ if (0 == memcmp (&my_identity.hashPubKey, key, sizeof (struct GNUNET_HashCode)))
bucket_idx = closest_bucket;
else
bucket_idx = GNUNET_MIN (closest_bucket, find_bucket (key));
@@ -1803,6 +1858,19 @@ handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer,
1, GNUNET_NO);
}
+ if (LOG_ROUTE_DETAILS_STDERR)
+ {
+ char *tmp;
+
+ tmp = GNUNET_strdup (GNUNET_i2s (&my_identity));
+ fprintf (stderr, "XDHT GET %s: %s(%u)<-%s\n",
+ GNUNET_h2s (&get->key), tmp, getpid(),
+ GNUNET_i2s (peer));
+ GNUNET_free (tmp);
+ }
+
+
+
/* FIXME Path */
GDS_CLIENTS_process_get (options,
type,
@@ -1917,12 +1985,27 @@ handle_dht_p2p_result (void *cls, const struct GNUNET_PeerIdentity *peer,
if (NULL != GDS_transport_handle)
{
GNUNET_TRANSPORT_offer_hello (GDS_transport_handle, h, NULL, NULL);
- GNUNET_TRANSPORT_try_connect (GDS_transport_handle, &pid);
+ if (GNUNET_YES !=
+ disable_try_connect)
+ GNUNET_TRANSPORT_try_connect (GDS_transport_handle, &pid, NULL, NULL); /*FIXME TRY_CONNECT change */
}
}
}
}
+
+ if (LOG_ROUTE_DETAILS_STDERR)
+ {
+ char *tmp;
+
+ tmp = GNUNET_strdup (GNUNET_i2s (&my_identity));
+ fprintf (stderr,
+ "XDHT RESULT %s: %s(%u)<-%s\n",
+ GNUNET_h2s (&prm->key), tmp,
+ getpid(), GNUNET_i2s (peer));
+ GNUNET_free (tmp);
+ }
+
/* append 'peer' to 'get_path' */
{
struct GNUNET_PeerIdentity xget_path[get_path_length + 1];
@@ -1974,18 +2057,20 @@ GDS_NEIGHBOURS_init ()
};
unsigned long long temp_config_num;
+ disable_try_connect
+ = GNUNET_CONFIGURATION_get_value_yesno (GDS_cfg, "DHT", "DISABLE_TRY_CONNECT");
if (GNUNET_OK ==
GNUNET_CONFIGURATION_get_value_number (GDS_cfg, "DHT", "bucket_size",
&temp_config_num))
bucket_size = (unsigned int) temp_config_num;
atsAPI = GNUNET_ATS_performance_init (GDS_cfg, NULL, NULL);
coreAPI =
- GNUNET_CORE_connect (GDS_cfg, 1, NULL, &core_init, &handle_core_connect,
+ GNUNET_CORE_connect (GDS_cfg, NULL, &core_init, &handle_core_connect,
&handle_core_disconnect, NULL, GNUNET_NO, NULL,
GNUNET_NO, core_handlers);
if (coreAPI == NULL)
return GNUNET_SYSERR;
- all_known_peers = GNUNET_CONTAINER_multihashmap_create (256);
+ all_known_peers = GNUNET_CONTAINER_multihashmap_create (256, GNUNET_NO);
return GNUNET_OK;
}