diff options
author | Nathan S. Evans <evans@in.tum.de> | 2010-08-31 19:53:22 +0000 |
---|---|---|
committer | Nathan S. Evans <evans@in.tum.de> | 2010-08-31 19:53:22 +0000 |
commit | fa549db57599c0148d91f386889cafad07b223ad (patch) | |
tree | 0e0998d41f32eaeaa6143cef4e93910d8cabb5dd /src/dht/gnunet-service-dht.c | |
parent | 789666b489d86a209676511af74e810c92585151 (diff) | |
download | gnunet-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.c | 77 |
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 */ | |||
697 | static struct GNUNET_CONTAINER_MultiHashMap *all_known_peers; | 706 | static struct GNUNET_CONTAINER_MultiHashMap *all_known_peers; |
698 | 707 | ||
699 | /** | 708 | /** |
709 | * Recently seen find peer requests. | ||
710 | */ | ||
711 | static struct GNUNET_CONTAINER_MultiHashMap *recent_find_peer_requests; | ||
712 | |||
713 | /** | ||
700 | * Maximum size for each bucket. | 714 | * Maximum size for each bucket. |
701 | */ | 715 | */ |
702 | static unsigned int bucket_size = DEFAULT_BUCKET_SIZE; /* Initially equal to DEFAULT_BUCKET_SIZE */ | 716 | static 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 | ||
2118 | static void | ||
2119 | remove_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 | */ |
2100 | static void | 2133 | static void |
2101 | handle_dht_find_peer (void *cls, | 2134 | handle_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 | { |