aboutsummaryrefslogtreecommitdiff
path: root/src/dht/gnunet-service-dht.c
diff options
context:
space:
mode:
authorNathan S. Evans <evans@in.tum.de>2010-08-31 19:53:22 +0000
committerNathan S. Evans <evans@in.tum.de>2010-08-31 19:53:22 +0000
commitfa549db57599c0148d91f386889cafad07b223ad (patch)
tree0e0998d41f32eaeaa6143cef4e93910d8cabb5dd /src/dht/gnunet-service-dht.c
parent789666b489d86a209676511af74e810c92585151 (diff)
downloadgnunet-fa549db57599c0148d91f386889cafad07b223ad.tar.gz
gnunet-fa549db57599c0148d91f386889cafad07b223ad.zip
various fixes, improvements, fubars, for dht... still tuning
Diffstat (limited to 'src/dht/gnunet-service-dht.c')
-rw-r--r--src/dht/gnunet-service-dht.c77
1 files changed, 66 insertions, 11 deletions
diff --git a/src/dht/gnunet-service-dht.c b/src/dht/gnunet-service-dht.c
index e28682ee4..958b1d8b2 100644
--- a/src/dht/gnunet-service-dht.c
+++ b/src/dht/gnunet-service-dht.c
@@ -99,7 +99,7 @@
99/** 99/**
100 * Default replication parameter for find peer messages sent by the dht service. 100 * Default replication parameter for find peer messages sent by the dht service.
101 */ 101 */
102#define DHT_DEFAULT_FIND_PEER_REPLICATION 10 102#define DHT_DEFAULT_FIND_PEER_REPLICATION 1
103 103
104/** 104/**
105 * Default options for find peer requests sent by the dht service. 105 * Default options for find peer requests sent by the dht service.
@@ -469,6 +469,15 @@ struct DHTRouteSource
469 * Task to remove this entry on timeout. 469 * Task to remove this entry on timeout.
470 */ 470 */
471 GNUNET_SCHEDULER_TaskIdentifier delete_task; 471 GNUNET_SCHEDULER_TaskIdentifier delete_task;
472
473 /**
474 * Bloomfilter of peers we have already sent back as
475 * replies to the initial request. Allows us to not
476 * forward the same peer multiple times for a find peer
477 * request.
478 */
479 struct GNUNET_CONTAINER_BloomFilter *find_peers_responded;
480
472}; 481};
473 482
474/** 483/**
@@ -697,6 +706,11 @@ static struct PeerBucket k_buckets[MAX_BUCKETS]; /* From 0 to MAX_BUCKETS - 1 */
697static struct GNUNET_CONTAINER_MultiHashMap *all_known_peers; 706static struct GNUNET_CONTAINER_MultiHashMap *all_known_peers;
698 707
699/** 708/**
709 * Recently seen find peer requests.
710 */
711static struct GNUNET_CONTAINER_MultiHashMap *recent_find_peer_requests;
712
713/**
700 * Maximum size for each bucket. 714 * Maximum size for each bucket.
701 */ 715 */
702static unsigned int bucket_size = DEFAULT_BUCKET_SIZE; /* Initially equal to DEFAULT_BUCKET_SIZE */ 716static unsigned int bucket_size = DEFAULT_BUCKET_SIZE; /* Initially equal to DEFAULT_BUCKET_SIZE */
@@ -1832,6 +1846,7 @@ static int route_result_message(void *cls,
1832 { 1846 {
1833 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%s:%s Received non-HELLO message type in find peer result message!\n", my_short_id, "DHT"); 1847 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%s:%s Received non-HELLO message type in find peer result message!\n", my_short_id, "DHT");
1834 GNUNET_break_op(0); 1848 GNUNET_break_op(0);
1849 return GNUNET_NO;
1835 } 1850 }
1836 else /* We have a valid hello, and peer id stored in new_peer */ 1851 else /* We have a valid hello, and peer id stored in new_peer */
1837 { 1852 {
@@ -1885,6 +1900,18 @@ static int route_result_message(void *cls,
1885 pos = record->head; 1900 pos = record->head;
1886 while (pos != NULL) 1901 while (pos != NULL)
1887 { 1902 {
1903 if (ntohs(msg->type) == GNUNET_MESSAGE_TYPE_DHT_FIND_PEER_RESULT) /* If we have already forwarded this peer id, don't do it again! */
1904 {
1905 if (GNUNET_YES == GNUNET_CONTAINER_bloomfilter_test (pos->find_peers_responded, &new_peer.hashPubKey))
1906 {
1907 increment_stats("# find peer responses NOT forwarded (bloom match)");
1908 pos = pos->next;
1909 continue;
1910 }
1911 else
1912 GNUNET_CONTAINER_bloomfilter_add(pos->find_peers_responded, &new_peer.hashPubKey);
1913 }
1914
1888 if (0 == memcmp(&pos->source, &my_identity, sizeof(struct GNUNET_PeerIdentity))) /* Local client (or DHT) initiated request! */ 1915 if (0 == memcmp(&pos->source, &my_identity, sizeof(struct GNUNET_PeerIdentity))) /* Local client (or DHT) initiated request! */
1889 { 1916 {
1890#if DEBUG_DHT 1917#if DEBUG_DHT
@@ -1919,7 +1946,7 @@ static int route_result_message(void *cls,
1919 if (message_context->bloom == NULL) 1946 if (message_context->bloom == NULL)
1920 message_context->bloom = GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, DHT_BLOOM_K); 1947 message_context->bloom = GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, DHT_BLOOM_K);
1921 GNUNET_CONTAINER_bloomfilter_add (message_context->bloom, &my_identity.hashPubKey); 1948 GNUNET_CONTAINER_bloomfilter_add (message_context->bloom, &my_identity.hashPubKey);
1922 if (GNUNET_NO == GNUNET_CONTAINER_bloomfilter_test (message_context->bloom, &peer_info->id.hashPubKey)) 1949 if ((GNUNET_NO == GNUNET_CONTAINER_bloomfilter_test (message_context->bloom, &peer_info->id.hashPubKey)))
1923 { 1950 {
1924#if DEBUG_DHT 1951#if DEBUG_DHT
1925 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1952 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -2088,6 +2115,12 @@ handle_dht_get (void *cls,
2088 return results; 2115 return results;
2089} 2116}
2090 2117
2118static void
2119remove_recent_find_peer(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2120{
2121 GNUNET_HashCode *key = cls;
2122 GNUNET_CONTAINER_multihashmap_remove(recent_find_peer_requests, key, key);
2123}
2091 2124
2092/** 2125/**
2093 * Server handler for initiating local dht find peer requests 2126 * Server handler for initiating local dht find peer requests
@@ -2099,7 +2132,7 @@ handle_dht_get (void *cls,
2099 */ 2132 */
2100static void 2133static void
2101handle_dht_find_peer (void *cls, 2134handle_dht_find_peer (void *cls,
2102 const struct GNUNET_MessageHeader *find_msg, 2135 const struct GNUNET_MessageHeader *find_msg,
2103 struct DHT_MessageContext *message_context) 2136 struct DHT_MessageContext *message_context)
2104{ 2137{
2105 struct GNUNET_MessageHeader *find_peer_result; 2138 struct GNUNET_MessageHeader *find_peer_result;
@@ -2108,6 +2141,8 @@ handle_dht_find_peer (void *cls,
2108 struct GNUNET_CONTAINER_BloomFilter *incoming_bloom; 2141 struct GNUNET_CONTAINER_BloomFilter *incoming_bloom;
2109 size_t hello_size; 2142 size_t hello_size;
2110 size_t tsize; 2143 size_t tsize;
2144 GNUNET_HashCode *recent_hash;
2145
2111 find_peer_message = (struct GNUNET_DHT_FindPeerMessage *)find_msg; 2146 find_peer_message = (struct GNUNET_DHT_FindPeerMessage *)find_msg;
2112#if DEBUG_DHT 2147#if DEBUG_DHT
2113 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2148 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -2135,6 +2170,16 @@ handle_dht_find_peer (void *cls,
2135 } 2170 }
2136 GNUNET_CONTAINER_bloomfilter_free(incoming_bloom); 2171 GNUNET_CONTAINER_bloomfilter_free(incoming_bloom);
2137 2172
2173 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains(recent_find_peer_requests, &message_context->key)) /* We have recently responded to a find peer request for this peer! */
2174 {
2175 increment_stats("# dht find peer requests ignored (recently seen!)");
2176 return;
2177 }
2178 recent_hash = GNUNET_malloc(sizeof(GNUNET_HashCode));
2179 memcpy(recent_hash, &message_context->key, sizeof(GNUNET_HashCode));
2180 GNUNET_CONTAINER_multihashmap_put (recent_find_peer_requests, &message_context->key, NULL, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
2181 GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 30), &remove_recent_find_peer, &message_context->key);
2182
2138 /* Simplistic find_peer functionality, always return our hello */ 2183 /* Simplistic find_peer functionality, always return our hello */
2139 hello_size = ntohs(my_hello->size); 2184 hello_size = ntohs(my_hello->size);
2140 tsize = hello_size + sizeof (struct GNUNET_MessageHeader); 2185 tsize = hello_size + sizeof (struct GNUNET_MessageHeader);
@@ -2286,7 +2331,7 @@ get_forward_count (unsigned int hop_count, size_t target_replication)
2286 2331
2287 /** 2332 /**
2288 * If we are behaving in strict kademlia mode, send multiple initial requests, 2333 * If we are behaving in strict kademlia mode, send multiple initial requests,
2289 * but then only send to 1 or 0 peers. 2334 * but then only send to 1 or 0 peers based strictly on the number of hops.
2290 */ 2335 */
2291 if (strict_kademlia == GNUNET_YES) 2336 if (strict_kademlia == GNUNET_YES)
2292 { 2337 {
@@ -2322,14 +2367,12 @@ get_forward_count (unsigned int hop_count, size_t target_replication)
2322 return 0; 2367 return 0;
2323 } 2368 }
2324 target_count = /* target_count is ALWAYS < 1 unless replication is < 1 */ 2369 target_count = /* target_count is ALWAYS < 1 unless replication is < 1 */
2325 target_replication / (target_replication * (hop_count + 1) + diameter); 2370 (double)target_replication / ((double)target_replication * (hop_count + 1) + diameter);
2326#if NONSENSE 2371
2327 target_value = 0; 2372 target_value = 0;
2328 while (target_value < target_count) 2373 while (target_value < target_count)
2329 target_value++; /* target_value is ALWAYS 1 after this "loop" */ 2374 target_value++; /* target_value is ALWAYS 1 after this "loop", right? Because target_count is always > 0, right? Or does it become 0.00000... at some point because the hop count is so high? */
2330#else 2375
2331 target_value = 1;
2332#endif
2333 if ((target_count + 1 - target_value) > 2376 if ((target_count + 1 - target_value) >
2334 GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 2377 GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
2335 RAND_MAX) / RAND_MAX) 2378 RAND_MAX) / RAND_MAX)
@@ -2589,6 +2632,8 @@ remove_forward_entry (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2589 GNUNET_assert(GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove(forward_list.hashmap, &record->key, record)); 2632 GNUNET_assert(GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove(forward_list.hashmap, &record->key, record));
2590 GNUNET_free(record); 2633 GNUNET_free(record);
2591 } 2634 }
2635 if (source_info->find_peers_responded != NULL)
2636 GNUNET_CONTAINER_bloomfilter_free(source_info->find_peers_responded);
2592 GNUNET_free(source_info); 2637 GNUNET_free(source_info);
2593} 2638}
2594 2639
@@ -2623,6 +2668,8 @@ static int cache_response(void *cls, struct DHT_MessageContext *msg_ctx)
2623 GNUNET_free(record); 2668 GNUNET_free(record);
2624 } 2669 }
2625 GNUNET_SCHEDULER_cancel(sched, source_info->delete_task); 2670 GNUNET_SCHEDULER_cancel(sched, source_info->delete_task);
2671 if (source_info->find_peers_responded != NULL)
2672 GNUNET_CONTAINER_bloomfilter_free(source_info->find_peers_responded);
2626 GNUNET_free(source_info); 2673 GNUNET_free(source_info);
2627 current_size = GNUNET_CONTAINER_multihashmap_size(forward_list.hashmap); 2674 current_size = GNUNET_CONTAINER_multihashmap_size(forward_list.hashmap);
2628 } 2675 }
@@ -2653,6 +2700,7 @@ static int cache_response(void *cls, struct DHT_MessageContext *msg_ctx)
2653 source_info = GNUNET_malloc(sizeof(struct DHTRouteSource)); 2700 source_info = GNUNET_malloc(sizeof(struct DHTRouteSource));
2654 source_info->record = record; 2701 source_info->record = record;
2655 source_info->delete_task = GNUNET_SCHEDULER_add_delayed(sched, DHT_FORWARD_TIMEOUT, &remove_forward_entry, source_info); 2702 source_info->delete_task = GNUNET_SCHEDULER_add_delayed(sched, DHT_FORWARD_TIMEOUT, &remove_forward_entry, source_info);
2703 source_info->find_peers_responded = GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, DHT_BLOOM_K);
2656 memcpy(&source_info->source, msg_ctx->peer, sizeof(struct GNUNET_PeerIdentity)); 2704 memcpy(&source_info->source, msg_ctx->peer, sizeof(struct GNUNET_PeerIdentity));
2657 GNUNET_CONTAINER_DLL_insert_after(record->head, record->tail, record->tail, source_info); 2705 GNUNET_CONTAINER_DLL_insert_after(record->head, record->tail, record->tail, source_info);
2658 if (msg_ctx->client != NULL) /* For local request, set timeout so high it effectively never gets pushed out */ 2706 if (msg_ctx->client != NULL) /* For local request, set timeout so high it effectively never gets pushed out */
@@ -2686,6 +2734,7 @@ static int route_message(void *cls,
2686 struct DHT_MessageContext *message_context) 2734 struct DHT_MessageContext *message_context)
2687{ 2735{
2688 int i; 2736 int i;
2737 int global_closest;
2689 struct PeerInfo *selected; 2738 struct PeerInfo *selected;
2690#if DEBUG_DHT_ROUTING > 1 2739#if DEBUG_DHT_ROUTING > 1
2691 struct PeerInfo *nearest; 2740 struct PeerInfo *nearest;
@@ -2693,6 +2742,7 @@ static int route_message(void *cls,
2693 unsigned int forward_count; 2742 unsigned int forward_count;
2694 struct RecentRequest *recent_req; 2743 struct RecentRequest *recent_req;
2695 GNUNET_HashCode unique_hash; 2744 GNUNET_HashCode unique_hash;
2745 char *stat_forward_count;
2696#if DEBUG_DHT_ROUTING 2746#if DEBUG_DHT_ROUTING
2697 int ret; 2747 int ret;
2698#endif 2748#endif
@@ -2717,15 +2767,19 @@ static int route_message(void *cls,
2717 /* Semantics of this call means we find whether we are the closest peer out of those already 2767 /* Semantics of this call means we find whether we are the closest peer out of those already
2718 * routed to on this messages path. 2768 * routed to on this messages path.
2719 */ 2769 */
2770 global_closest = am_closest_peer(&message_context->key, NULL);
2720 message_context->closest = am_closest_peer(&message_context->key, message_context->bloom); 2771 message_context->closest = am_closest_peer(&message_context->key, message_context->bloom);
2721 forward_count = get_forward_count(message_context->hop_count, message_context->replication); 2772 forward_count = get_forward_count(message_context->hop_count, message_context->replication);
2722 2773 GNUNET_asprintf(&stat_forward_count, "# forward counts of %d", forward_count);
2774 increment_stats(stat_forward_count);
2775 GNUNET_free(stat_forward_count);
2723 if (message_context->bloom == NULL) 2776 if (message_context->bloom == NULL)
2724 message_context->bloom = GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, DHT_BLOOM_K); 2777 message_context->bloom = GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, DHT_BLOOM_K);
2725 2778
2726 if ((stop_on_closest == GNUNET_YES) && (message_context->closest == GNUNET_YES) && (ntohs(msg->type) == GNUNET_MESSAGE_TYPE_DHT_PUT)) 2779 if ((stop_on_closest == GNUNET_YES) && (message_context->closest == GNUNET_YES) && (ntohs(msg->type) == GNUNET_MESSAGE_TYPE_DHT_PUT))
2727 forward_count = 0; 2780 forward_count = 0;
2728 2781
2782
2729#if DEBUG_DHT_ROUTING 2783#if DEBUG_DHT_ROUTING
2730 if (forward_count == 0) 2784 if (forward_count == 0)
2731 ret = GNUNET_SYSERR; 2785 ret = GNUNET_SYSERR;
@@ -3594,6 +3648,7 @@ run (void *cls,
3594 forward_list.hashmap = GNUNET_CONTAINER_multihashmap_create(MAX_OUTSTANDING_FORWARDS / 10); 3648 forward_list.hashmap = GNUNET_CONTAINER_multihashmap_create(MAX_OUTSTANDING_FORWARDS / 10);
3595 forward_list.minHeap = GNUNET_CONTAINER_heap_create(GNUNET_CONTAINER_HEAP_ORDER_MIN); 3649 forward_list.minHeap = GNUNET_CONTAINER_heap_create(GNUNET_CONTAINER_HEAP_ORDER_MIN);
3596 all_known_peers = GNUNET_CONTAINER_multihashmap_create(MAX_BUCKETS / 8); 3650 all_known_peers = GNUNET_CONTAINER_multihashmap_create(MAX_BUCKETS / 8);
3651 recent_find_peer_requests = GNUNET_CONTAINER_multihashmap_create(MAX_BUCKETS / 8);
3597 GNUNET_assert(all_known_peers != NULL); 3652 GNUNET_assert(all_known_peers != NULL);
3598 if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno(cfg, "dht_testing", "mysql_logging")) 3653 if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno(cfg, "dht_testing", "mysql_logging"))
3599 { 3654 {