diff options
author | Christian Grothoff <christian@grothoff.org> | 2011-09-13 10:17:17 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2011-09-13 10:17:17 +0000 |
commit | d56d318035765539f8c064b91d8bf8bd8d93d78c (patch) | |
tree | b602e4ff32ac27944c77237f394a0ebde2cd02cc /src/dht/gnunet-service-dht.c | |
parent | bf51e53605502d2fb868655451b5d169994a62d5 (diff) | |
download | gnunet-d56d318035765539f8c064b91d8bf8bd8d93d78c.tar.gz gnunet-d56d318035765539f8c064b91d8bf8bd8d93d78c.zip |
remove non-binary peer selection strategies
Diffstat (limited to 'src/dht/gnunet-service-dht.c')
-rw-r--r-- | src/dht/gnunet-service-dht.c | 466 |
1 files changed, 16 insertions, 450 deletions
diff --git a/src/dht/gnunet-service-dht.c b/src/dht/gnunet-service-dht.c index 055fbe1fd..4b61ec67b 100644 --- a/src/dht/gnunet-service-dht.c +++ b/src/dht/gnunet-service-dht.c | |||
@@ -171,38 +171,6 @@ | |||
171 | */ | 171 | */ |
172 | #define MAX_REPLY_TIMES 8 | 172 | #define MAX_REPLY_TIMES 8 |
173 | 173 | ||
174 | enum ConvergenceOptions | ||
175 | { | ||
176 | /** | ||
177 | * Use the linear method for convergence. | ||
178 | */ | ||
179 | DHT_CONVERGE_LINEAR, | ||
180 | |||
181 | /** | ||
182 | * Converge using a fast converging square | ||
183 | * function. | ||
184 | */ | ||
185 | DHT_CONVERGE_SQUARE, | ||
186 | |||
187 | /** | ||
188 | * Converge using a slower exponential | ||
189 | * function. | ||
190 | */ | ||
191 | DHT_CONVERGE_EXPONENTIAL, | ||
192 | |||
193 | /** | ||
194 | * Don't do any special convergence, allow | ||
195 | * the algorithm to hopefully route to closer | ||
196 | * peers more often. | ||
197 | */ | ||
198 | DHT_CONVERGE_RANDOM, | ||
199 | |||
200 | /** | ||
201 | * Binary convergence, start routing to closest | ||
202 | * only after set number of hops. | ||
203 | */ | ||
204 | DHT_CONVERGE_BINARY | ||
205 | }; | ||
206 | 174 | ||
207 | /** | 175 | /** |
208 | * Linked list of messages to send to clients. | 176 | * Linked list of messages to send to clients. |
@@ -693,10 +661,6 @@ struct RepublishContext | |||
693 | 661 | ||
694 | }; | 662 | }; |
695 | 663 | ||
696 | /** | ||
697 | * Which kind of convergence will we be using? | ||
698 | */ | ||
699 | static enum ConvergenceOptions converge_option; | ||
700 | 664 | ||
701 | /** | 665 | /** |
702 | * Modifier for the convergence function | 666 | * Modifier for the convergence function |
@@ -3210,144 +3174,6 @@ am_closest_peer (const GNUNET_HashCode * target, | |||
3210 | 3174 | ||
3211 | 3175 | ||
3212 | /** | 3176 | /** |
3213 | * Return this peers adjusted value based on the convergence | ||
3214 | * function chosen. This is the key function for randomized | ||
3215 | * routing decisions. | ||
3216 | * | ||
3217 | * @param target the key of the request | ||
3218 | * @param peer the peer we would like the value of | ||
3219 | * @param hops number of hops this message has already traveled | ||
3220 | * | ||
3221 | * @return bit distance from target to peer raised to an exponent | ||
3222 | * adjusted based on the current routing convergence algorithm | ||
3223 | * | ||
3224 | */ | ||
3225 | static unsigned long long | ||
3226 | converge_distance (const GNUNET_HashCode * target, struct PeerInfo *peer, | ||
3227 | unsigned int hops) | ||
3228 | { | ||
3229 | unsigned long long ret; | ||
3230 | unsigned int other_matching_bits; | ||
3231 | double base_converge_modifier = .1; /* Value that "looks" good (when plotted), have to start somewhere */ | ||
3232 | double temp_modifier; | ||
3233 | double calc_value; | ||
3234 | double exponent; | ||
3235 | int curr_max_hops; | ||
3236 | |||
3237 | if (use_max_hops) | ||
3238 | curr_max_hops = max_hops; | ||
3239 | else | ||
3240 | curr_max_hops = (estimate_diameter () + 1) * 2; | ||
3241 | |||
3242 | if (converge_modifier > 0) | ||
3243 | temp_modifier = converge_modifier * base_converge_modifier; | ||
3244 | else | ||
3245 | { | ||
3246 | temp_modifier = base_converge_modifier; | ||
3247 | base_converge_modifier = 0.0; | ||
3248 | } | ||
3249 | |||
3250 | GNUNET_assert (temp_modifier > 0); | ||
3251 | |||
3252 | other_matching_bits = | ||
3253 | GNUNET_CRYPTO_hash_matching_bits (target, &peer->id.hashPubKey); | ||
3254 | |||
3255 | switch (converge_option) | ||
3256 | { | ||
3257 | case DHT_CONVERGE_RANDOM: | ||
3258 | return 1; /* Always return 1, choose equally among all peers */ | ||
3259 | case DHT_CONVERGE_LINEAR: | ||
3260 | calc_value = hops * curr_max_hops * temp_modifier; | ||
3261 | break; | ||
3262 | case DHT_CONVERGE_SQUARE: | ||
3263 | /** | ||
3264 | * Simple square based curve. | ||
3265 | */ | ||
3266 | calc_value = | ||
3267 | (sqrt (hops) / sqrt (curr_max_hops)) * (curr_max_hops / | ||
3268 | (curr_max_hops * | ||
3269 | temp_modifier)); | ||
3270 | break; | ||
3271 | case DHT_CONVERGE_EXPONENTIAL: | ||
3272 | /** | ||
3273 | * Simple exponential curve. | ||
3274 | */ | ||
3275 | if (base_converge_modifier > 0) | ||
3276 | calc_value = (temp_modifier * hops * hops) / curr_max_hops; | ||
3277 | else | ||
3278 | calc_value = (hops * hops) / curr_max_hops; | ||
3279 | break; | ||
3280 | case DHT_CONVERGE_BINARY: | ||
3281 | /** | ||
3282 | * If below the cutoff, route randomly (return 1), | ||
3283 | * If above the cutoff, return the maximum possible | ||
3284 | * value first (always route to closest, because | ||
3285 | * they are sorted.) | ||
3286 | */ | ||
3287 | |||
3288 | if (hops >= converge_modifier) /* Past cutoff */ | ||
3289 | { | ||
3290 | return ULLONG_MAX; | ||
3291 | } | ||
3292 | /* Fall through */ | ||
3293 | default: | ||
3294 | return 1; | ||
3295 | } | ||
3296 | |||
3297 | /* Take the log (base e) of the number of bits matching the other peer */ | ||
3298 | exponent = log (other_matching_bits); | ||
3299 | |||
3300 | /* Check if we would overflow; our largest possible value is 2^64 approx. e^44.361419555836498 */ | ||
3301 | if (exponent * calc_value >= 44.361419555836498) | ||
3302 | return ULLONG_MAX; | ||
3303 | |||
3304 | /* Clear errno and all math exceptions */ | ||
3305 | errno = 0; | ||
3306 | feclearexcept (FE_ALL_EXCEPT); | ||
3307 | ret = (unsigned long long) pow (other_matching_bits, calc_value); | ||
3308 | if ((errno != 0) || | ||
3309 | fetestexcept (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW)) | ||
3310 | { | ||
3311 | if (0 != fetestexcept (FE_OVERFLOW)) | ||
3312 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "FE_OVERFLOW\n"); | ||
3313 | if (0 != fetestexcept (FE_INVALID)) | ||
3314 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "FE_INVALID\n"); | ||
3315 | if (0 != fetestexcept (FE_UNDERFLOW)) | ||
3316 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "FE_UNDERFLOW\n"); | ||
3317 | return 0; | ||
3318 | } | ||
3319 | else | ||
3320 | return ret; | ||
3321 | } | ||
3322 | |||
3323 | /** | ||
3324 | * Comparison function for two struct PeerInfo's | ||
3325 | * which have already had their matching bits to | ||
3326 | * some target calculated. | ||
3327 | * | ||
3328 | * @param p1 a pointer pointer to a struct PeerInfo | ||
3329 | * @param p2 a pointer pointer to a struct PeerInfo | ||
3330 | * | ||
3331 | * @return 0 if equidistant to target, | ||
3332 | * -1 if p1 is closer, | ||
3333 | * 1 if p2 is closer | ||
3334 | */ | ||
3335 | static int | ||
3336 | compare_peers (const void *p1, const void *p2) | ||
3337 | { | ||
3338 | struct PeerInfo **first = (struct PeerInfo **) p1; | ||
3339 | struct PeerInfo **second = (struct PeerInfo **) p2; | ||
3340 | |||
3341 | if ((*first)->matching_bits > (*second)->matching_bits) | ||
3342 | return -1; | ||
3343 | if ((*first)->matching_bits < (*second)->matching_bits) | ||
3344 | return 1; | ||
3345 | else | ||
3346 | return 0; | ||
3347 | } | ||
3348 | |||
3349 | |||
3350 | /** | ||
3351 | * Select a peer from the routing table that would be a good routing | 3177 | * Select a peer from the routing table that would be a good routing |
3352 | * destination for sending a message for "target". The resulting peer | 3178 | * destination for sending a message for "target". The resulting peer |
3353 | * must not be in the set of blocked peers.<p> | 3179 | * must not be in the set of blocked peers.<p> |
@@ -3367,30 +3193,18 @@ select_peer (const GNUNET_HashCode * target, | |||
3367 | struct GNUNET_CONTAINER_BloomFilter *bloom, unsigned int hops) | 3193 | struct GNUNET_CONTAINER_BloomFilter *bloom, unsigned int hops) |
3368 | { | 3194 | { |
3369 | unsigned int bc; | 3195 | unsigned int bc; |
3370 | unsigned int i; | ||
3371 | unsigned int count; | 3196 | unsigned int count; |
3372 | unsigned int offset; | 3197 | unsigned int selected; |
3373 | int closest_bucket; | ||
3374 | struct PeerInfo *pos; | 3198 | struct PeerInfo *pos; |
3375 | struct PeerInfo *sorted_closest[bucket_size]; | ||
3376 | unsigned long long temp_converge_distance; | ||
3377 | unsigned long long total_distance; | ||
3378 | unsigned long long selected; | ||
3379 | |||
3380 | #if DEBUG_DHT > 1 | ||
3381 | unsigned long long stats_total_distance; | ||
3382 | double sum; | ||
3383 | #endif | ||
3384 | /* For kademlia */ | ||
3385 | unsigned int distance; | 3199 | unsigned int distance; |
3386 | unsigned int largest_distance; | 3200 | unsigned int largest_distance; |
3387 | struct PeerInfo *chosen; | 3201 | struct PeerInfo *chosen; |
3388 | 3202 | ||
3389 | total_distance = 0; | 3203 | /** If we are doing kademlia routing (saves some cycles) */ |
3390 | /** If we are doing kademlia routing, or converge is binary (saves some cycles) */ | 3204 | if ( (strict_kademlia == GNUNET_YES) || |
3391 | if ((strict_kademlia == GNUNET_YES) || | 3205 | (hops >= converge_modifier) ) |
3392 | ((converge_option == DHT_CONVERGE_BINARY) && (hops >= converge_modifier))) | ||
3393 | { | 3206 | { |
3207 | /* greedy selection (closest peer that is not in bloomfilter) */ | ||
3394 | largest_distance = 0; | 3208 | largest_distance = 0; |
3395 | chosen = NULL; | 3209 | chosen = NULL; |
3396 | for (bc = lowest_bucket; bc < MAX_BUCKETS; bc++) | 3210 | for (bc = lowest_bucket; bc < MAX_BUCKETS; bc++) |
@@ -3414,284 +3228,59 @@ select_peer (const GNUNET_HashCode * target, | |||
3414 | pos = pos->next; | 3228 | pos = pos->next; |
3415 | } | 3229 | } |
3416 | } | 3230 | } |
3417 | |||
3418 | if ((largest_distance > 0) && (chosen != NULL)) | 3231 | if ((largest_distance > 0) && (chosen != NULL)) |
3419 | { | 3232 | { |
3420 | GNUNET_CONTAINER_bloomfilter_add (bloom, &chosen->id.hashPubKey); | 3233 | GNUNET_CONTAINER_bloomfilter_add (bloom, &chosen->id.hashPubKey); |
3421 | return chosen; | 3234 | return chosen; |
3422 | } | 3235 | } |
3423 | else | 3236 | return NULL; /* no peer available or we are the closest */ |
3424 | { | ||
3425 | return NULL; | ||
3426 | } | ||
3427 | } | 3237 | } |
3428 | 3238 | ||
3429 | /* GNUnet-style */ | ||
3430 | total_distance = 0; | ||
3431 | /* Three steps: order peers in closest bucket (most matching bits). | ||
3432 | * Then go over all LOWER buckets (matching same bits we do) | ||
3433 | * Then go over all HIGHER buckets (matching less then we do) | ||
3434 | */ | ||
3435 | 3239 | ||
3436 | closest_bucket = find_current_bucket (target); | 3240 | /* select "random" peer */ |
3437 | GNUNET_assert (closest_bucket >= lowest_bucket); | 3241 | /* count number of peers that are available and not filtered */ |
3438 | pos = k_buckets[closest_bucket].head; | ||
3439 | count = 0; | 3242 | count = 0; |
3440 | offset = 0; /* Need offset as well as count in case peers are bloomfiltered */ | 3243 | for (bc = lowest_bucket; bc < MAX_BUCKETS; bc++) |
3441 | memset (sorted_closest, 0, sizeof (sorted_closest)); | ||
3442 | /* Put any peers in the closest bucket in the sorting array */ | ||
3443 | while ((pos != NULL) && (count < bucket_size)) | ||
3444 | { | ||
3445 | if (GNUNET_YES == | ||
3446 | GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey)) | ||
3447 | { | ||
3448 | count++; | ||
3449 | pos = pos->next; | ||
3450 | continue; /* Ignore bloomfiltered peers */ | ||
3451 | } | ||
3452 | pos->matching_bits = | ||
3453 | GNUNET_CRYPTO_hash_matching_bits (&pos->id.hashPubKey, target); | ||
3454 | sorted_closest[offset] = pos; | ||
3455 | pos = pos->next; | ||
3456 | offset++; | ||
3457 | count++; | ||
3458 | } | ||
3459 | |||
3460 | /* Sort the peers in descending order */ | ||
3461 | qsort (&sorted_closest[0], offset, sizeof (struct PeerInfo *), | ||
3462 | &compare_peers); | ||
3463 | |||
3464 | /* Put the sorted closest peers into the possible bins first, in case of overflow. */ | ||
3465 | for (i = 0; i < offset; i++) | ||
3466 | { | ||
3467 | temp_converge_distance = | ||
3468 | converge_distance (target, sorted_closest[i], hops); | ||
3469 | if (GNUNET_YES == | ||
3470 | GNUNET_CONTAINER_bloomfilter_test (bloom, | ||
3471 | &sorted_closest[i]->id.hashPubKey)) | ||
3472 | break; /* Ignore bloomfiltered peers */ | ||
3473 | if (total_distance + temp_converge_distance > total_distance) /* Handle largest case and overflow */ | ||
3474 | total_distance += temp_converge_distance; | ||
3475 | else | ||
3476 | break; /* overflow case */ | ||
3477 | } | ||
3478 | |||
3479 | /* Now handle peers in lower buckets (matches same # of bits as target) */ | ||
3480 | for (bc = lowest_bucket; bc < closest_bucket; bc++) | ||
3481 | { | 3244 | { |
3482 | pos = k_buckets[bc].head; | 3245 | pos = k_buckets[bc].head; |
3483 | count = 0; | ||
3484 | while ((pos != NULL) && (count < bucket_size)) | 3246 | while ((pos != NULL) && (count < bucket_size)) |
3485 | { | 3247 | { |
3486 | if (GNUNET_YES == | 3248 | if (GNUNET_YES == |
3487 | GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey)) | 3249 | GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey)) |
3488 | { | 3250 | { |
3489 | count++; | ||
3490 | pos = pos->next; | 3251 | pos = pos->next; |
3491 | continue; /* Ignore bloomfiltered peers */ | 3252 | continue; /* Ignore bloomfiltered peers */ |
3492 | } | 3253 | } |
3493 | temp_converge_distance = converge_distance (target, pos, hops); | ||
3494 | if (total_distance + temp_converge_distance > total_distance) /* Handle largest case and overflow */ | ||
3495 | total_distance += temp_converge_distance; | ||
3496 | else | ||
3497 | break; /* overflow case */ | ||
3498 | pos = pos->next; | ||
3499 | count++; | 3254 | count++; |
3500 | } | ||
3501 | } | ||
3502 | |||
3503 | /* Now handle all the further away peers */ | ||
3504 | for (bc = closest_bucket + 1; bc < MAX_BUCKETS; bc++) | ||
3505 | { | ||
3506 | pos = k_buckets[bc].head; | ||
3507 | count = 0; | ||
3508 | while ((pos != NULL) && (count < bucket_size)) | ||
3509 | { | ||
3510 | if (GNUNET_YES == | ||
3511 | GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey)) | ||
3512 | { | ||
3513 | count++; | ||
3514 | pos = pos->next; | ||
3515 | continue; /* Ignore bloomfiltered peers */ | ||
3516 | } | ||
3517 | temp_converge_distance = converge_distance (target, pos, hops); | ||
3518 | if (total_distance + temp_converge_distance > total_distance) /* Handle largest case and overflow */ | ||
3519 | total_distance += temp_converge_distance; | ||
3520 | else | ||
3521 | break; /* overflow case */ | ||
3522 | pos = pos->next; | 3255 | pos = pos->next; |
3523 | count++; | ||
3524 | } | 3256 | } |
3525 | } | 3257 | } |
3526 | 3258 | if (count == 0) /* No peers to select from! */ | |
3527 | if (total_distance == 0) /* No peers to select from! */ | ||
3528 | { | 3259 | { |
3529 | increment_stats ("# failed to select peer"); | 3260 | increment_stats ("# failed to select peer"); |
3530 | return NULL; | 3261 | return NULL; |
3531 | } | 3262 | } |
3532 | |||
3533 | #if DEBUG_DHT_ROUTING > 1 | ||
3534 | sum = 0.0; | ||
3535 | /* PRINT STATS */ | ||
3536 | /* Put the sorted closest peers into the possible bins first, in case of overflow. */ | ||
3537 | stats_total_distance = 0; | ||
3538 | for (i = 0; i < offset; i++) | ||
3539 | { | ||
3540 | if (GNUNET_YES == | ||
3541 | GNUNET_CONTAINER_bloomfilter_test (bloom, | ||
3542 | &sorted_closest[i]->id.hashPubKey)) | ||
3543 | break; /* Ignore bloomfiltered peers */ | ||
3544 | temp_converge_distance = | ||
3545 | converge_distance (target, sorted_closest[i], hops); | ||
3546 | if (stats_total_distance + temp_converge_distance > stats_total_distance) /* Handle largest case and overflow */ | ||
3547 | stats_total_distance += temp_converge_distance; | ||
3548 | else | ||
3549 | break; /* overflow case */ | ||
3550 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
3551 | "Choose %d matching bits (%d bits match me) (%.2f percent) converge ret %llu\n", | ||
3552 | GNUNET_CRYPTO_hash_matching_bits (&sorted_closest[i]->id. | ||
3553 | hashPubKey, target), | ||
3554 | GNUNET_CRYPTO_hash_matching_bits (&sorted_closest[i]->id. | ||
3555 | hashPubKey, | ||
3556 | &my_identity.hashPubKey), | ||
3557 | (temp_converge_distance / (double) total_distance) * 100, | ||
3558 | temp_converge_distance); | ||
3559 | } | ||
3560 | |||
3561 | /* Now handle peers in lower buckets (matches same # of bits as target) */ | ||
3562 | for (bc = lowest_bucket; bc < closest_bucket; bc++) | ||
3563 | { | ||
3564 | pos = k_buckets[bc].head; | ||
3565 | count = 0; | ||
3566 | while ((pos != NULL) && (count < bucket_size)) | ||
3567 | { | ||
3568 | if (GNUNET_YES == | ||
3569 | GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey)) | ||
3570 | { | ||
3571 | count++; | ||
3572 | pos = pos->next; | ||
3573 | continue; /* Ignore bloomfiltered peers */ | ||
3574 | } | ||
3575 | temp_converge_distance = converge_distance (target, pos, hops); | ||
3576 | if (stats_total_distance + temp_converge_distance > stats_total_distance) /* Handle largest case and overflow */ | ||
3577 | stats_total_distance += temp_converge_distance; | ||
3578 | else | ||
3579 | break; /* overflow case */ | ||
3580 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
3581 | "Choose %d matching bits (%d bits match me) (%.2f percent) converge ret %llu\n", | ||
3582 | GNUNET_CRYPTO_hash_matching_bits (&pos->id.hashPubKey, | ||
3583 | target), | ||
3584 | GNUNET_CRYPTO_hash_matching_bits (&pos->id.hashPubKey, | ||
3585 | &my_identity.hashPubKey), | ||
3586 | (temp_converge_distance / (double) total_distance) * 100, | ||
3587 | temp_converge_distance); | ||
3588 | pos = pos->next; | ||
3589 | count++; | ||
3590 | } | ||
3591 | } | ||
3592 | |||
3593 | /* Now handle all the further away peers */ | ||
3594 | for (bc = closest_bucket + 1; bc < MAX_BUCKETS; bc++) | ||
3595 | { | ||
3596 | pos = k_buckets[bc].head; | ||
3597 | count = 0; | ||
3598 | while ((pos != NULL) && (count < bucket_size)) | ||
3599 | { | ||
3600 | if (GNUNET_YES == | ||
3601 | GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey)) | ||
3602 | { | ||
3603 | count++; | ||
3604 | pos = pos->next; | ||
3605 | continue; /* Ignore bloomfiltered peers */ | ||
3606 | } | ||
3607 | temp_converge_distance = converge_distance (target, pos, hops); | ||
3608 | if (stats_total_distance + temp_converge_distance > stats_total_distance) /* Handle largest case and overflow */ | ||
3609 | stats_total_distance += temp_converge_distance; | ||
3610 | else | ||
3611 | break; /* overflow case */ | ||
3612 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
3613 | "Choose %d matching bits (%d bits match me) (%.2f percent) converge ret %llu\n", | ||
3614 | GNUNET_CRYPTO_hash_matching_bits (&pos->id.hashPubKey, | ||
3615 | target), | ||
3616 | GNUNET_CRYPTO_hash_matching_bits (&pos->id.hashPubKey, | ||
3617 | &my_identity.hashPubKey), | ||
3618 | (temp_converge_distance / (double) total_distance) * 100, | ||
3619 | temp_converge_distance); | ||
3620 | pos = pos->next; | ||
3621 | count++; | ||
3622 | } | ||
3623 | } | ||
3624 | /* END PRINT STATS */ | ||
3625 | #endif | ||
3626 | |||
3627 | /* Now actually choose a peer */ | 3263 | /* Now actually choose a peer */ |
3628 | selected = | 3264 | selected = |
3629 | GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, total_distance); | 3265 | GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, count); |
3630 | 3266 | count = 0; | |
3631 | /* Go over closest sorted peers. */ | 3267 | for (bc = lowest_bucket; bc < MAX_BUCKETS; bc++) |
3632 | for (i = 0; i < offset; i++) | ||
3633 | { | ||
3634 | if (GNUNET_YES == | ||
3635 | GNUNET_CONTAINER_bloomfilter_test (bloom, | ||
3636 | &sorted_closest[i]->id.hashPubKey)) | ||
3637 | break; /* Ignore bloomfiltered peers */ | ||
3638 | temp_converge_distance = | ||
3639 | converge_distance (target, sorted_closest[i], hops); | ||
3640 | if (temp_converge_distance >= selected) | ||
3641 | return sorted_closest[i]; | ||
3642 | else | ||
3643 | selected -= temp_converge_distance; | ||
3644 | } | ||
3645 | |||
3646 | /* Now handle peers in lower buckets (matches same # of bits as target) */ | ||
3647 | for (bc = lowest_bucket; bc < closest_bucket; bc++) | ||
3648 | { | ||
3649 | pos = k_buckets[bc].head; | ||
3650 | count = 0; | ||
3651 | while ((pos != NULL) && (count < bucket_size)) | ||
3652 | { | ||
3653 | if (GNUNET_YES == | ||
3654 | GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey)) | ||
3655 | { | ||
3656 | count++; | ||
3657 | pos = pos->next; | ||
3658 | continue; /* Ignore bloomfiltered peers */ | ||
3659 | } | ||
3660 | temp_converge_distance = converge_distance (target, pos, hops); | ||
3661 | if (temp_converge_distance >= selected) | ||
3662 | return pos; | ||
3663 | else | ||
3664 | selected -= temp_converge_distance; | ||
3665 | pos = pos->next; | ||
3666 | count++; | ||
3667 | } | ||
3668 | } | ||
3669 | |||
3670 | /* Now handle all the further away peers */ | ||
3671 | for (bc = closest_bucket + 1; bc < MAX_BUCKETS; bc++) | ||
3672 | { | 3268 | { |
3673 | pos = k_buckets[bc].head; | 3269 | pos = k_buckets[bc].head; |
3674 | count = 0; | ||
3675 | while ((pos != NULL) && (count < bucket_size)) | 3270 | while ((pos != NULL) && (count < bucket_size)) |
3676 | { | 3271 | { |
3677 | if (GNUNET_YES == | 3272 | if (GNUNET_YES == |
3678 | GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey)) | 3273 | GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey)) |
3679 | { | 3274 | { |
3680 | count++; | ||
3681 | pos = pos->next; | 3275 | pos = pos->next; |
3682 | continue; /* Ignore bloomfiltered peers */ | 3276 | continue; /* Ignore bloomfiltered peers */ |
3683 | } | 3277 | } |
3684 | temp_converge_distance = converge_distance (target, pos, hops); | 3278 | if (0 == selected) |
3685 | if (temp_converge_distance >= selected) | 3279 | return pos; |
3686 | return pos; | ||
3687 | else | ||
3688 | selected -= temp_converge_distance; | ||
3689 | pos = pos->next; | 3280 | pos = pos->next; |
3690 | count++; | ||
3691 | } | 3281 | } |
3692 | } | 3282 | } |
3693 | 3283 | GNUNET_break (0); | |
3694 | increment_stats ("# failed to select peer"); | ||
3695 | return NULL; | 3284 | return NULL; |
3696 | } | 3285 | } |
3697 | 3286 | ||
@@ -5491,29 +5080,6 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, | |||
5491 | } | 5080 | } |
5492 | #endif | 5081 | #endif |
5493 | 5082 | ||
5494 | converge_option = DHT_CONVERGE_BINARY; | ||
5495 | if (GNUNET_YES == | ||
5496 | GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht", "converge_linear")) | ||
5497 | { | ||
5498 | converge_option = DHT_CONVERGE_LINEAR; | ||
5499 | } | ||
5500 | else if (GNUNET_YES == | ||
5501 | GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht", | ||
5502 | "converge_exponential")) | ||
5503 | { | ||
5504 | converge_option = DHT_CONVERGE_EXPONENTIAL; | ||
5505 | } | ||
5506 | else if (GNUNET_YES == | ||
5507 | GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht", "converge_random")) | ||
5508 | { | ||
5509 | converge_option = DHT_CONVERGE_RANDOM; | ||
5510 | } | ||
5511 | else if (GNUNET_YES == | ||
5512 | GNUNET_CONFIGURATION_get_value_yesno (cfg, "dht", "converge_binary")) | ||
5513 | { | ||
5514 | converge_option = DHT_CONVERGE_BINARY; | ||
5515 | } | ||
5516 | |||
5517 | converge_modifier = 4.0; | 5083 | converge_modifier = 4.0; |
5518 | if (GNUNET_OK == | 5084 | if (GNUNET_OK == |
5519 | GNUNET_CONFIGURATION_get_value_string (cfg, "dht", "converge_modifier", | 5085 | GNUNET_CONFIGURATION_get_value_string (cfg, "dht", "converge_modifier", |