aboutsummaryrefslogtreecommitdiff
path: root/src/dht
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-09-27 13:23:19 +0000
committerChristian Grothoff <christian@grothoff.org>2011-09-27 13:23:19 +0000
commit087fa2688ea9aa9fe9e8b0b3bf4a59e1479b1dbe (patch)
treedce5c0dd40106b1ce88442094f9a6a41ec1cdc77 /src/dht
parent6ac27138723d4609749e38f84e0a06c96610a735 (diff)
downloadgnunet-087fa2688ea9aa9fe9e8b0b3bf4a59e1479b1dbe.tar.gz
gnunet-087fa2688ea9aa9fe9e8b0b3bf4a59e1479b1dbe.zip
do not route requests that were perfectly satisfied
Diffstat (limited to 'src/dht')
-rw-r--r--src/dht/gnunet-service-dht_datacache.c14
-rw-r--r--src/dht/gnunet-service-dht_datacache.h3
-rw-r--r--src/dht/gnunet-service-dht_neighbours.c238
3 files changed, 129 insertions, 126 deletions
diff --git a/src/dht/gnunet-service-dht_datacache.c b/src/dht/gnunet-service-dht_datacache.c
index fc1983419..4ac0a815b 100644
--- a/src/dht/gnunet-service-dht_datacache.c
+++ b/src/dht/gnunet-service-dht_datacache.c
@@ -142,6 +142,10 @@ struct GetRequestContext
142 */ 142 */
143 uint32_t reply_bf_mutator; 143 uint32_t reply_bf_mutator;
144 144
145 /**
146 * Return value to give back.
147 */
148 enum GNUNET_BLOCK_EvaluationResult eval;
145}; 149};
146 150
147 151
@@ -192,6 +196,7 @@ datacache_get_iterator (void *cls, struct GNUNET_TIME_Absolute exp,
192 ctx->xquery_size, 196 ctx->xquery_size,
193 rdata, 197 rdata,
194 rdata_size); 198 rdata_size);
199 ctx->eval = eval;
195 switch (eval) 200 switch (eval)
196 { 201 {
197 case GNUNET_BLOCK_EVALUATION_OK_LAST: 202 case GNUNET_BLOCK_EVALUATION_OK_LAST:
@@ -223,7 +228,7 @@ datacache_get_iterator (void *cls, struct GNUNET_TIME_Absolute exp,
223 type); 228 type);
224 break; 229 break;
225 } 230 }
226 return GNUNET_OK; 231 return (eval == GNUNET_BLOCK_EVALUATION_OK_LAST) ? GNUNET_NO : GNUNET_OK;
227} 232}
228 233
229 234
@@ -236,8 +241,9 @@ datacache_get_iterator (void *cls, struct GNUNET_TIME_Absolute exp,
236 * @param xquery_size number of bytes in xquery 241 * @param xquery_size number of bytes in xquery
237 * @param reply_bf where the reply bf is (to be) stored, possibly updated, can be NULL 242 * @param reply_bf where the reply bf is (to be) stored, possibly updated, can be NULL
238 * @param reply_bf_mutator mutation value for reply_bf 243 * @param reply_bf_mutator mutation value for reply_bf
244 * @return evaluation result for the local replies
239 */ 245 */
240void 246enum GNUNET_BLOCK_EvaluationResult
241GDS_DATACACHE_handle_get (const GNUNET_HashCode *key, 247GDS_DATACACHE_handle_get (const GNUNET_HashCode *key,
242 enum GNUNET_BLOCK_Type type, 248 enum GNUNET_BLOCK_Type type,
243 const void *xquery, 249 const void *xquery,
@@ -248,7 +254,8 @@ GDS_DATACACHE_handle_get (const GNUNET_HashCode *key,
248 struct GetRequestContext ctx; 254 struct GetRequestContext ctx;
249 255
250 if (datacache == NULL) 256 if (datacache == NULL)
251 return; 257 return GNUNET_BLOCK_EVALUATION_REQUEST_VALID;
258 ctx.eval = GNUNET_BLOCK_EVALUATION_REQUEST_VALID;
252 ctx.key = *key; 259 ctx.key = *key;
253 ctx.xquery = xquery; 260 ctx.xquery = xquery;
254 ctx.xquery_size = xquery_size; 261 ctx.xquery_size = xquery_size;
@@ -256,6 +263,7 @@ GDS_DATACACHE_handle_get (const GNUNET_HashCode *key,
256 ctx.reply_bf_mutator = reply_bf_mutator; 263 ctx.reply_bf_mutator = reply_bf_mutator;
257 (void) GNUNET_DATACACHE_get (datacache, key, type, 264 (void) GNUNET_DATACACHE_get (datacache, key, type,
258 &datacache_get_iterator, &ctx); 265 &datacache_get_iterator, &ctx);
266 return ctx.eval;
259} 267}
260 268
261 269
diff --git a/src/dht/gnunet-service-dht_datacache.h b/src/dht/gnunet-service-dht_datacache.h
index dce15bd7d..ccd854570 100644
--- a/src/dht/gnunet-service-dht_datacache.h
+++ b/src/dht/gnunet-service-dht_datacache.h
@@ -61,8 +61,9 @@ GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration,
61 * @param xquery_size number of bytes in xquery 61 * @param xquery_size number of bytes in xquery
62 * @param reply_bf where the reply bf is (to be) stored, possibly updated!, can be NULL 62 * @param reply_bf where the reply bf is (to be) stored, possibly updated!, can be NULL
63 * @param reply_bf_mutator mutation value for reply_bf 63 * @param reply_bf_mutator mutation value for reply_bf
64 * @return evaluation result for the local replies
64 */ 65 */
65void 66enum GNUNET_BLOCK_EvaluationResult
66GDS_DATACACHE_handle_get (const GNUNET_HashCode *key, 67GDS_DATACACHE_handle_get (const GNUNET_HashCode *key,
67 enum GNUNET_BLOCK_Type type, 68 enum GNUNET_BLOCK_Type type,
68 const void *xquery, 69 const void *xquery,
diff --git a/src/dht/gnunet-service-dht_neighbours.c b/src/dht/gnunet-service-dht_neighbours.c
index cebf0e91f..7411c964d 100644
--- a/src/dht/gnunet-service-dht_neighbours.c
+++ b/src/dht/gnunet-service-dht_neighbours.c
@@ -43,6 +43,7 @@
43#include "gnunet-service-dht.h" 43#include "gnunet-service-dht.h"
44#include "gnunet-service-dht_clients.h" 44#include "gnunet-service-dht_clients.h"
45#include "gnunet-service-dht_datacache.h" 45#include "gnunet-service-dht_datacache.h"
46#include "gnunet-service-dht_neighbours.h"
46#include "gnunet-service-dht_nse.h" 47#include "gnunet-service-dht_nse.h"
47#include "gnunet-service-dht_routing.h" 48#include "gnunet-service-dht_routing.h"
48#include <fenv.h> 49#include <fenv.h>
@@ -535,6 +536,97 @@ update_core_preference (void *cls,
535 536
536 537
537/** 538/**
539 * Closure for 'add_known_to_bloom'.
540 */
541struct BloomConstructorContext
542{
543 /**
544 * Bloom filter under construction.
545 */
546 struct GNUNET_CONTAINER_BloomFilter *bloom;
547
548 /**
549 * Mutator to use.
550 */
551 uint32_t bf_mutator;
552};
553
554
555/**
556 * Add each of the peers we already know to the bloom filter of
557 * the request so that we don't get duplicate HELLOs.
558 *
559 * @param cls the 'struct BloomConstructorContext'.
560 * @param key peer identity to add to the bloom filter
561 * @param value value the peer information (unused)
562 * @return GNUNET_YES (we should continue to iterate)
563 */
564static int
565add_known_to_bloom (void *cls, const GNUNET_HashCode * key, void *value)
566{
567 struct BloomConstructorContext *ctx = cls;
568 GNUNET_HashCode mh;
569
570 GNUNET_BLOCK_mingle_hash (key, ctx->bf_mutator, &mh);
571 GNUNET_CONTAINER_bloomfilter_add (ctx->bloom, &mh);
572 return GNUNET_YES;
573}
574
575
576/**
577 * Task to send a find peer message for our own peer identifier
578 * so that we can find the closest peers in the network to ourselves
579 * and attempt to connect to them.
580 *
581 * @param cls closure for this task
582 * @param tc the context under which the task is running
583 */
584static void
585send_find_peer_message (void *cls,
586 const struct GNUNET_SCHEDULER_TaskContext *tc)
587{
588 struct GNUNET_TIME_Relative next_send_time;
589 struct BloomConstructorContext bcc;
590
591 find_peer_task = GNUNET_SCHEDULER_NO_TASK;
592 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
593 return;
594 if (newly_found_peers > bucket_size)
595 {
596 /* If we are finding many peers already, no need to send out our request right now! */
597 find_peer_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
598 &send_find_peer_message, NULL);
599 newly_found_peers = 0;
600 return;
601 }
602 bcc.bf_mutator = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX);
603 bcc.bloom =
604 GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, DHT_BLOOM_K);
605 GNUNET_CONTAINER_multihashmap_iterate (all_known_peers,
606 &add_known_to_bloom,
607 &bcc);
608 // FIXME: pass priority!?
609 GDS_NEIGHBOURS_handle_get (GNUNET_BLOCK_TYPE_DHT_HELLO,
610 GNUNET_DHT_RO_FIND_PEER,
611 FIND_PEER_REPLICATION_LEVEL,
612 0,
613 &my_identity.hashPubKey,
614 NULL, 0,
615 bcc.bloom, bcc.bf_mutator, NULL);
616 GNUNET_CONTAINER_bloomfilter_free (bcc.bloom);
617 /* schedule next round */
618 newly_found_peers = 0;
619 next_send_time.rel_value =
620 (DHT_MAXIMUM_FIND_PEER_INTERVAL.rel_value / 2) +
621 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
622 DHT_MAXIMUM_FIND_PEER_INTERVAL.rel_value / 2);
623 find_peer_task = GNUNET_SCHEDULER_add_delayed (next_send_time,
624 &send_find_peer_message,
625 NULL);
626}
627
628
629/**
538 * Method called whenever a peer connects. 630 * Method called whenever a peer connects.
539 * 631 *
540 * @param cls closure 632 * @param cls closure
@@ -579,6 +671,12 @@ handle_core_connect (void *cls, const struct GNUNET_PeerIdentity *peer,
579 GNUNET_CONTAINER_multihashmap_put (all_known_peers, 671 GNUNET_CONTAINER_multihashmap_put (all_known_peers,
580 &peer->hashPubKey, ret, 672 &peer->hashPubKey, ret,
581 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 673 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
674 if (1 == GNUNET_CONTAINER_multihashmap_size (all_known_peers))
675 {
676 /* got a first connection, good time to start with FIND PEER requests... */
677 find_peer_task = GNUNET_SCHEDULER_add_now (&send_find_peer_message,
678 NULL);
679 }
582} 680}
583 681
584 682
@@ -1224,9 +1322,9 @@ GDS_NEIGHBOURS_handle_reply (const struct GNUNET_PeerIdentity *target,
1224 struct GNUNET_TIME_Absolute expiration_time, 1322 struct GNUNET_TIME_Absolute expiration_time,
1225 const GNUNET_HashCode *key, 1323 const GNUNET_HashCode *key,
1226 unsigned int put_path_length, 1324 unsigned int put_path_length,
1227 struct GNUNET_PeerIdentity *put_path, 1325 const struct GNUNET_PeerIdentity *put_path,
1228 unsigned int get_path_length, 1326 unsigned int get_path_length,
1229 struct GNUNET_PeerIdentity *get_path, 1327 const struct GNUNET_PeerIdentity *get_path,
1230 const void *data, 1328 const void *data,
1231 size_t data_size) 1329 size_t data_size)
1232{ 1330{
@@ -1280,97 +1378,6 @@ GDS_NEIGHBOURS_handle_reply (const struct GNUNET_PeerIdentity *target,
1280 1378
1281 1379
1282/** 1380/**
1283 * Closure for 'add_known_to_bloom'.
1284 */
1285struct BloomConstructorContext
1286{
1287 /**
1288 * Bloom filter under construction.
1289 */
1290 struct GNUNET_CONTAINER_BloomFilter *bloom;
1291
1292 /**
1293 * Mutator to use.
1294 */
1295 uint32_t bf_mutator;
1296};
1297
1298
1299/**
1300 * Add each of the peers we already know to the bloom filter of
1301 * the request so that we don't get duplicate HELLOs.
1302 *
1303 * @param cls the 'struct BloomConstructorContext'.
1304 * @param key peer identity to add to the bloom filter
1305 * @param value value the peer information (unused)
1306 * @return GNUNET_YES (we should continue to iterate)
1307 */
1308static int
1309add_known_to_bloom (void *cls, const GNUNET_HashCode * key, void *value)
1310{
1311 struct BloomConstructorContext *ctx = cls;
1312 GNUNET_HashCode mh;
1313
1314 GNUNET_BLOCK_mingle_hash (key, ctx->bf_mutator, &mh);
1315 GNUNET_CONTAINER_bloomfilter_add (ctx->bloom, &mh);
1316 return GNUNET_YES;
1317}
1318
1319
1320/**
1321 * Task to send a find peer message for our own peer identifier
1322 * so that we can find the closest peers in the network to ourselves
1323 * and attempt to connect to them.
1324 *
1325 * @param cls closure for this task
1326 * @param tc the context under which the task is running
1327 */
1328static void
1329send_find_peer_message (void *cls,
1330 const struct GNUNET_SCHEDULER_TaskContext *tc)
1331{
1332 struct GNUNET_TIME_Relative next_send_time;
1333 struct BloomConstructorContext bcc;
1334
1335 find_peer_task = GNUNET_SCHEDULER_NO_TASK;
1336 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
1337 return;
1338 if (newly_found_peers > bucket_size)
1339 {
1340 /* If we are finding many peers already, no need to send out our request right now! */
1341 find_peer_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
1342 &send_find_peer_message, NULL);
1343 newly_found_peers = 0;
1344 return;
1345 }
1346 bcc.bf_mutator = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX);
1347 bcc.bloom =
1348 GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, DHT_BLOOM_K);
1349 GNUNET_CONTAINER_multihashmap_iterate (all_known_peers,
1350 &add_known_to_bloom,
1351 &bcc);
1352 // FIXME: pass priority!?
1353 GDS_NEIGHBOURS_handle_get (GNUNET_BLOCK_TYPE_DHT_HELLO,
1354 GNUNET_DHT_RO_FIND_PEER,
1355 FIND_PEER_REPLICATION_LEVEL,
1356 0,
1357 &my_identity.hashPubKey,
1358 NULL, 0,
1359 bcc.bloom, bcc.bf_mutator, NULL);
1360 GNUNET_CONTAINER_bloomfilter_free (bcc.bloom);
1361 /* schedule next round */
1362 newly_found_peers = 0;
1363 next_send_time.rel_value =
1364 (DHT_MAXIMUM_FIND_PEER_INTERVAL.rel_value / 2) +
1365 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
1366 DHT_MAXIMUM_FIND_PEER_INTERVAL.rel_value / 2);
1367 find_peer_task = GNUNET_SCHEDULER_add_delayed (next_send_time,
1368 &send_find_peer_message,
1369 NULL);
1370}
1371
1372
1373/**
1374 * To be called on core init/fail. 1381 * To be called on core init/fail.
1375 * 1382 *
1376 * @param cls service closure 1383 * @param cls service closure
@@ -1383,20 +1390,8 @@ core_init (void *cls, struct GNUNET_CORE_Handle *server,
1383 const struct GNUNET_PeerIdentity *identity, 1390 const struct GNUNET_PeerIdentity *identity,
1384 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *publicKey) 1391 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *publicKey)
1385{ 1392{
1386 struct GNUNET_TIME_Relative next_send_time;
1387
1388 GNUNET_assert (server != NULL); 1393 GNUNET_assert (server != NULL);
1389 my_identity = *identity; 1394 my_identity = *identity;
1390 /* FIXME: do upon 1st connect instead! */
1391 next_send_time.rel_value =
1392 DHT_MINIMUM_FIND_PEER_INTERVAL.rel_value +
1393 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
1394 (DHT_MAXIMUM_FIND_PEER_INTERVAL.rel_value /
1395 2) -
1396 DHT_MINIMUM_FIND_PEER_INTERVAL.rel_value);
1397 find_peer_task = GNUNET_SCHEDULER_add_delayed (next_send_time,
1398 &send_find_peer_message,
1399 NULL);
1400} 1395}
1401 1396
1402 1397
@@ -1686,26 +1681,25 @@ handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer,
1686 } 1681 }
1687 else 1682 else
1688 { 1683 {
1689 GDS_DATACACHE_handle_get (&get->key, 1684 eval = GDS_DATACACHE_handle_get (&get->key,
1690 type, 1685 type,
1691 xquery, xquery_size, 1686 xquery, xquery_size,
1692 &reply_bf, 1687 &reply_bf,
1693 get->bf_mutator); 1688 get->bf_mutator);
1694 /* FIXME: should track if the local lookup resulted in a
1695 definitive result and then NOT do P2P forwarding */
1696 } 1689 }
1697 } 1690 }
1698 1691
1699 /* P2P forwarding */ 1692 /* P2P forwarding */
1700 GDS_NEIGHBOURS_handle_get (type, 1693 if (eval != GNUNET_BLOCK_EVALUATION_OK_LAST)
1701 options, 1694 GDS_NEIGHBOURS_handle_get (type,
1702 ntohl (get->desired_replication_level), 1695 options,
1703 ntohl (get->hop_count) + 1, /* CHECK: where (else) do we do +1? */ 1696 ntohl (get->desired_replication_level),
1704 &get->key, 1697 ntohl (get->hop_count) + 1, /* CHECK: where (else) do we do +1? */
1705 xquery, xquery_size, 1698 &get->key,
1706 reply_bf, 1699 xquery, xquery_size,
1707 get->bf_mutator, 1700 reply_bf,
1708 peer_bf); 1701 get->bf_mutator,
1702 peer_bf);
1709 /* clean up */ 1703 /* clean up */
1710 if (NULL != reply_bf) 1704 if (NULL != reply_bf)
1711 GNUNET_CONTAINER_bloomfilter_free (reply_bf); 1705 GNUNET_CONTAINER_bloomfilter_free (reply_bf);