aboutsummaryrefslogtreecommitdiff
path: root/src/dht/gnunet-service-dht.c
diff options
context:
space:
mode:
authorNathan S. Evans <evans@in.tum.de>2010-08-11 15:48:56 +0000
committerNathan S. Evans <evans@in.tum.de>2010-08-11 15:48:56 +0000
commit5c51bf63fa7cca2d96c6b2f9318b3fd805ac3628 (patch)
tree0f29aebffd76cdcfbd5678b8156e248abe2876ba /src/dht/gnunet-service-dht.c
parent1b0834b9cb28cc6dfa3984ace3bfcb5d5f57e84f (diff)
downloadgnunet-5c51bf63fa7cca2d96c6b2f9318b3fd805ac3628.tar.gz
gnunet-5c51bf63fa7cca2d96c6b2f9318b3fd805ac3628.zip
fix for kademlia routing
Diffstat (limited to 'src/dht/gnunet-service-dht.c')
-rw-r--r--src/dht/gnunet-service-dht.c243
1 files changed, 152 insertions, 91 deletions
diff --git a/src/dht/gnunet-service-dht.c b/src/dht/gnunet-service-dht.c
index fd9694fee..9c301183b 100644
--- a/src/dht/gnunet-service-dht.c
+++ b/src/dht/gnunet-service-dht.c
@@ -69,9 +69,12 @@
69 69
70#define DHT_DEFAULT_FIND_PEER_REPLICATION 10 70#define DHT_DEFAULT_FIND_PEER_REPLICATION 10
71 71
72#define DHT_MAX_RECENT 100
73
72#define DHT_DEFAULT_FIND_PEER_OPTIONS GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE 74#define DHT_DEFAULT_FIND_PEER_OPTIONS GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE
73 75
74#define DHT_MINIMUM_FIND_PEER_INTERVAL GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 1) 76#define DHT_MINIMUM_FIND_PEER_INTERVAL GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 1)
77
75#define DHT_MAXIMUM_FIND_PEER_INTERVAL GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 5) 78#define DHT_MAXIMUM_FIND_PEER_INTERVAL GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 5)
76 79
77/** 80/**
@@ -351,7 +354,6 @@ struct DHT_MessageContext
351 */ 354 */
352struct DHTRouteSource 355struct DHTRouteSource
353{ 356{
354
355 /** 357 /**
356 * This is a DLL. 358 * This is a DLL.
357 */ 359 */
@@ -439,6 +441,35 @@ struct DHTResults
439}; 441};
440 442
441/** 443/**
444 * DHT structure for recent requests.
445 */
446struct RecentRequests
447{
448 /*
449 * Min heap for removal upon reaching limit
450 */
451 struct GNUNET_CONTAINER_Heap *minHeap;
452
453 /*
454 * Hashmap for key based lookup
455 */
456 struct GNUNET_CONTAINER_MultiHashMap *hashmap;
457};
458
459struct RecentRequest
460{
461 GNUNET_HashCode key;
462 uint64_t uid;
463};
464
465
466#if 0
467/**
468 * Recent requests by hash/uid and by time inserted.
469 */
470static struct RecentRequests recent;
471#endif
472/**
442 * Don't use our routing algorithm, always route 473 * Don't use our routing algorithm, always route
443 * to closest peer; initially send requests to 3 474 * to closest peer; initially send requests to 3
444 * peers. 475 * peers.
@@ -2086,99 +2117,101 @@ select_peer (const GNUNET_HashCode * target,
2086 unsigned long long total_distance; 2117 unsigned long long total_distance;
2087 unsigned long long selected; 2118 unsigned long long selected;
2088 2119
2089if (strict_kademlia == GNUNET_YES) 2120 if (strict_kademlia == GNUNET_YES)
2090 { 2121 {
2091 largest_distance = 0; 2122 largest_distance = 0;
2092 chosen = NULL; 2123 chosen = NULL;
2093 for (bc = lowest_bucket; bc < MAX_BUCKETS; bc++) 2124 for (bc = lowest_bucket; bc < MAX_BUCKETS; bc++)
2094 { 2125 {
2095 pos = k_buckets[bc].head; 2126 pos = k_buckets[bc].head;
2096 count = 0; 2127 count = 0;
2097 while ((pos != NULL) && (count < bucket_size)) 2128 while ((pos != NULL) && (count < bucket_size))
2098 { 2129 {
2099 if (GNUNET_NO == GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey)) 2130 /* If we are doing strict Kademlia like routing, then checking the bloomfilter is basically cheating! */
2100 {
2101 distance = inverse_distance (target, &pos->id.hashPubKey);
2102 if (distance > largest_distance)
2103 {
2104 chosen = pos;
2105 largest_distance = distance;
2106 }
2107 }
2108 count++;
2109 pos = pos->next;
2110 }
2111 }
2112 2131
2113 if ((largest_distance > 0) && (chosen != NULL)) 2132 if (GNUNET_NO == GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey))
2114 { 2133 {
2115 GNUNET_CONTAINER_bloomfilter_add(bloom, &chosen->id.hashPubKey); 2134 distance = inverse_distance (target, &pos->id.hashPubKey);
2116 return chosen; 2135 if (distance > largest_distance)
2117 } 2136 {
2118 else 2137 chosen = pos;
2119 { 2138 largest_distance = distance;
2120 return NULL; 2139 }
2121 } 2140 }
2122 } 2141 count++;
2142 pos = pos->next;
2143 }
2144 }
2145
2146 if ((largest_distance > 0) && (chosen != NULL))
2147 {
2148 GNUNET_CONTAINER_bloomfilter_add(bloom, &chosen->id.hashPubKey);
2149 return chosen;
2150 }
2151 else
2152 {
2153 return NULL;
2154 }
2155 }
2123 else 2156 else
2124 { 2157 {
2125 /* GNUnet-style */ 2158 /* GNUnet-style */
2126 total_distance = 0; 2159 total_distance = 0;
2127 for (bc = lowest_bucket; bc < MAX_BUCKETS; bc++) 2160 for (bc = lowest_bucket; bc < MAX_BUCKETS; bc++)
2128 { 2161 {
2129 pos = k_buckets[bc].head; 2162 pos = k_buckets[bc].head;
2130 count = 0; 2163 count = 0;
2131 while ((pos != NULL) && (count < bucket_size)) 2164 while ((pos != NULL) && (count < bucket_size))
2132 { 2165 {
2133 if (GNUNET_NO == GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey)) 2166 if (GNUNET_NO == GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey))
2134 total_distance += (unsigned long long)inverse_distance (target, &pos->id.hashPubKey); 2167 total_distance += (unsigned long long)inverse_distance (target, &pos->id.hashPubKey);
2135#if DEBUG_DHT > 1 2168 #if DEBUG_DHT > 1
2136 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2169 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2137 "`%s:%s': Total distance is %llu, distance from %s to %s is %u\n", 2170 "`%s:%s': Total distance is %llu, distance from %s to %s is %u\n",
2138 my_short_id, "DHT", total_distance, GNUNET_i2s(&pos->id), GNUNET_h2s(target) , inverse_distance(target, &pos->id.hashPubKey)); 2171 my_short_id, "DHT", total_distance, GNUNET_i2s(&pos->id), GNUNET_h2s(target) , inverse_distance(target, &pos->id.hashPubKey));
2139#endif 2172 #endif
2140 pos = pos->next; 2173 pos = pos->next;
2141 count++; 2174 count++;
2142 } 2175 }
2143 } 2176 }
2144 if (total_distance == 0) 2177 if (total_distance == 0)
2145 { 2178 {
2146 return NULL; 2179 return NULL;
2147 } 2180 }
2148 2181
2149 selected = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, total_distance); 2182 selected = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, total_distance);
2150 for (bc = lowest_bucket; bc < MAX_BUCKETS; bc++) 2183 for (bc = lowest_bucket; bc < MAX_BUCKETS; bc++)
2151 { 2184 {
2152 pos = k_buckets[bc].head; 2185 pos = k_buckets[bc].head;
2153 count = 0; 2186 count = 0;
2154 while ((pos != NULL) && (count < bucket_size)) 2187 while ((pos != NULL) && (count < bucket_size))
2155 { 2188 {
2156 if (GNUNET_NO == GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey)) 2189 if (GNUNET_NO == GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey))
2157 { 2190 {
2158 distance = inverse_distance (target, &pos->id.hashPubKey); 2191 distance = inverse_distance (target, &pos->id.hashPubKey);
2159 if (distance > selected) 2192 if (distance > selected)
2160 return pos; 2193 return pos;
2161 selected -= distance; 2194 selected -= distance;
2162 } 2195 }
2163 else 2196 else
2164 { 2197 {
2165#if DEBUG_DHT 2198 #if DEBUG_DHT
2166 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2199 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2167 "`%s:%s': peer %s matches bloomfilter.\n", 2200 "`%s:%s': peer %s matches bloomfilter.\n",
2168 my_short_id, "DHT", GNUNET_i2s(&pos->id)); 2201 my_short_id, "DHT", GNUNET_i2s(&pos->id));
2169#endif 2202 #endif
2170 } 2203 }
2171 pos = pos->next; 2204 pos = pos->next;
2172 count++; 2205 count++;
2173 } 2206 }
2174 } 2207 }
2175#if DEBUG_DHT 2208 #if DEBUG_DHT
2176 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2209 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2177 "`%s:%s': peer %s matches bloomfilter.\n", 2210 "`%s:%s': peer %s matches bloomfilter.\n",
2178 my_short_id, "DHT", GNUNET_i2s(&pos->id)); 2211 my_short_id, "DHT", GNUNET_i2s(&pos->id));
2179#endif 2212 #endif
2180 return NULL; 2213 return NULL;
2181 } 2214 }
2182} 2215}
2183 2216
2184 2217
@@ -2323,6 +2356,8 @@ static int route_message(void *cls,
2323 return 0; 2356 return 0;
2324 } 2357 }
2325 2358
2359
2360
2326 increment_stats(STAT_ROUTES); 2361 increment_stats(STAT_ROUTES);
2327 message_context->closest = am_closest_peer(message_context->key); 2362 message_context->closest = am_closest_peer(message_context->key);
2328 forward_count = get_forward_count(message_context->hop_count, message_context->replication); 2363 forward_count = get_forward_count(message_context->hop_count, message_context->replication);
@@ -2387,7 +2422,33 @@ static int route_message(void *cls,
2387 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2422 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2388 "`%s': Message type (%d) not handled\n", "DHT", ntohs(msg->type)); 2423 "`%s': Message type (%d) not handled\n", "DHT", ntohs(msg->type));
2389 } 2424 }
2425#if 0
2426 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains(recent->hashmap, message_context->key))
2427 {
2428 if (GNUNET_SYSERR = GNUNET_CONTAINER_multihashmap_get_multiple (recent->hashmap, message_context->key, &find_matching_recent, &message_context)) /* Have too recently seen this request! */
2429 {
2430 forward_count = 0;
2431 }
2432 else /* Exact match not found, but same key found */
2433 {
2434 recent_req = GNUNET_CONTAINER_multihashmap_get(recent->hashmap, message_context->key);
2435 }
2436 }
2437 else
2438 {
2439 recent_req = GNUNET_malloc(sizeof(struct RecentRequest));
2440 recent_req->uid = message_context->unique_id;
2441 memcmp(&recent_req->key, message_context->key, sizeof(GNUNET_HashCode));
2442 recent_req->remove_task = GNUNET_SCHEDULER_add_delayed(sched, DEFAULT_RECENT_REMOVAL, &remove_recent, recent_req);
2443 GNUNET_CONTAINER_heap_insert(recent->minHeap, recent_req, GNUNET_TIME_absolute_get());
2444 GNUNET_CONTAINER_multihashmap_put(recent->hashmap, message_context->key, recent_req, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
2445 }
2390 2446
2447 if (GNUNET_CONTAINER_multihashmap_size(recent->hashmap) > DHT_MAX_RECENT)
2448 {
2449 remove_oldest_recent();
2450 }
2451#endif
2391 for (i = 0; i < forward_count; i++) 2452 for (i = 0; i < forward_count; i++)
2392 { 2453 {
2393 selected = select_peer(message_context->key, message_context->bloom); 2454 selected = select_peer(message_context->key, message_context->bloom);