diff options
-rw-r--r-- | src/dht/gnunet-service-dht_neighbours.c | 287 |
1 files changed, 150 insertions, 137 deletions
diff --git a/src/dht/gnunet-service-dht_neighbours.c b/src/dht/gnunet-service-dht_neighbours.c index 0fc42d2ef..6b1b73103 100644 --- a/src/dht/gnunet-service-dht_neighbours.c +++ b/src/dht/gnunet-service-dht_neighbours.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2009-2017, 2021 GNUnet e.V. | 3 | Copyright (C) 2009-2017, 2021, 2022 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 5 | GNUnet is free software: you can redistribute it and/or modify it |
6 | under the terms of the GNU Affero General Public License as published | 6 | under the terms of the GNU Affero General Public License as published |
@@ -25,21 +25,12 @@ | |||
25 | * @author Nathan Evans | 25 | * @author Nathan Evans |
26 | */ | 26 | */ |
27 | #include "platform.h" | 27 | #include "platform.h" |
28 | #include "gnunet_util_lib.h" | ||
29 | #include "gnunet_block_lib.h" | ||
30 | #include "gnunet_hello_lib.h" | ||
31 | #include "gnunet_constants.h" | 28 | #include "gnunet_constants.h" |
32 | #include "gnunet_protocols.h" | 29 | #include "gnunet_protocols.h" |
33 | #include "gnunet_nse_service.h" | ||
34 | #include "gnunet_ats_service.h" | 30 | #include "gnunet_ats_service.h" |
35 | #include "gnunet_core_service.h" | 31 | #include "gnunet_core_service.h" |
36 | #include "gnunet_datacache_lib.h" | ||
37 | #include "gnunet_transport_service.h" | ||
38 | #include "gnunet_hello_lib.h" | 32 | #include "gnunet_hello_lib.h" |
39 | #include "gnunet_dht_service.h" | ||
40 | #include "gnunet_statistics_service.h" | ||
41 | #include "gnunet-service-dht.h" | 33 | #include "gnunet-service-dht.h" |
42 | #include "gnunet-service-dht_datacache.h" | ||
43 | #include "gnunet-service-dht_hello.h" | 34 | #include "gnunet-service-dht_hello.h" |
44 | #include "gnunet-service-dht_neighbours.h" | 35 | #include "gnunet-service-dht_neighbours.h" |
45 | #include "gnunet-service-dht_nse.h" | 36 | #include "gnunet-service-dht_nse.h" |
@@ -55,7 +46,7 @@ | |||
55 | #define SANITY_CHECKS 1 | 46 | #define SANITY_CHECKS 1 |
56 | 47 | ||
57 | /** | 48 | /** |
58 | * How many buckets will we allow total. | 49 | * How many buckets will we allow in total. |
59 | */ | 50 | */ |
60 | #define MAX_BUCKETS sizeof(struct GNUNET_HashCode) * 8 | 51 | #define MAX_BUCKETS sizeof(struct GNUNET_HashCode) * 8 |
61 | 52 | ||
@@ -76,15 +67,23 @@ | |||
76 | 67 | ||
77 | /** | 68 | /** |
78 | * How long at least to wait before sending another find peer request. | 69 | * How long at least to wait before sending another find peer request. |
70 | * This is basically the frequency at which we will usually send out | ||
71 | * requests when we are 'perfectly' connected. | ||
79 | */ | 72 | */ |
80 | #define DHT_MINIMUM_FIND_PEER_INTERVAL GNUNET_TIME_relative_multiply ( \ | 73 | #define DHT_MINIMUM_FIND_PEER_INTERVAL GNUNET_TIME_relative_multiply ( \ |
81 | GNUNET_TIME_UNIT_SECONDS, 30) | 74 | GNUNET_TIME_UNIT_MINUTES, 2) |
82 | 75 | ||
83 | /** | 76 | /** |
84 | * How long at most to wait before sending another find peer request. | 77 | * How long to additionally wait on average per #bucket_size to send out the |
78 | * FIND PEER requests if we did successfully connect (!) to a a new peer and | ||
79 | * added it to a bucket (as counted in #newly_found_peers). This time is | ||
80 | * Multiplied by 100 * newly_found_peers / bucket_size to get the new delay | ||
81 | * for finding peers (the #DHT_MINIMUM_FIND_PEER_INTERVAL is still added on | ||
82 | * top). Also the range in which we randomize, so the effective value | ||
83 | * is half of the number given here. | ||
85 | */ | 84 | */ |
86 | #define DHT_MAXIMUM_FIND_PEER_INTERVAL GNUNET_TIME_relative_multiply ( \ | 85 | #define DHT_AVG_FIND_PEER_INTERVAL GNUNET_TIME_relative_multiply ( \ |
87 | GNUNET_TIME_UNIT_MINUTES, 10) | 86 | GNUNET_TIME_UNIT_SECONDS, 6) |
88 | 87 | ||
89 | /** | 88 | /** |
90 | * How long at most to wait for transmission of a GET request to another peer? | 89 | * How long at most to wait for transmission of a GET request to another peer? |
@@ -504,33 +503,34 @@ static void | |||
504 | try_connect (const struct GNUNET_PeerIdentity *pid, | 503 | try_connect (const struct GNUNET_PeerIdentity *pid, |
505 | const struct GNUNET_MessageHeader *h) | 504 | const struct GNUNET_MessageHeader *h) |
506 | { | 505 | { |
507 | int bucket; | 506 | int bucket_idx; |
508 | struct GNUNET_HashCode pid_hash; | 507 | struct GNUNET_HashCode pid_hash; |
509 | struct ConnectInfo *ci; | 508 | struct ConnectInfo *ci; |
510 | uint32_t strength; | 509 | uint32_t strength; |
510 | struct PeerBucket *bucket; | ||
511 | 511 | ||
512 | GNUNET_CRYPTO_hash (pid, | 512 | GNUNET_CRYPTO_hash (pid, |
513 | sizeof(struct GNUNET_PeerIdentity), | 513 | sizeof(struct GNUNET_PeerIdentity), |
514 | &pid_hash); | 514 | &pid_hash); |
515 | bucket = find_bucket (&pid_hash); | 515 | bucket_idx = find_bucket (&pid_hash); |
516 | if (bucket < 0) | 516 | if (bucket_idx < 0) |
517 | return; /* self? */ | 517 | { |
518 | GNUNET_break (0); | ||
519 | return; /* self!? */ | ||
520 | } | ||
521 | bucket = &k_buckets[bucket_idx]; | ||
518 | ci = GNUNET_CONTAINER_multipeermap_get (all_desired_peers, | 522 | ci = GNUNET_CONTAINER_multipeermap_get (all_desired_peers, |
519 | pid); | 523 | pid); |
520 | 524 | if (bucket->peers_size < bucket_size) | |
521 | if (k_buckets[bucket].peers_size < bucket_size) | 525 | strength = (bucket_size - bucket->peers_size) * bucket_idx; |
522 | strength = (bucket_size - k_buckets[bucket].peers_size) * bucket; | ||
523 | else | 526 | else |
524 | strength = bucket; /* minimum value of connectivity */ | 527 | strength = 0; |
525 | if (GNUNET_YES == | 528 | if (GNUNET_YES == |
526 | GNUNET_CONTAINER_multipeermap_contains (all_connected_peers, | 529 | GNUNET_CONTAINER_multipeermap_contains (all_connected_peers, |
527 | pid)) | 530 | pid)) |
528 | strength *= 2; /* double for connected peers */ | 531 | strength *= 2; /* double for connected peers */ |
529 | else if (k_buckets[bucket].peers_size > bucket_size) | 532 | if ( (0 == strength) && |
530 | strength = 0; /* bucket full, we really do not care about more */ | 533 | (NULL != ci) ) |
531 | |||
532 | if ((0 == strength) && | ||
533 | (NULL != ci)) | ||
534 | { | 534 | { |
535 | /* release request */ | 535 | /* release request */ |
536 | GNUNET_assert (GNUNET_YES == | 536 | GNUNET_assert (GNUNET_YES == |
@@ -548,22 +548,24 @@ try_connect (const struct GNUNET_PeerIdentity *pid, | |||
548 | ci, | 548 | ci, |
549 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | 549 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); |
550 | } | 550 | } |
551 | if ((NULL != ci->oh) && | 551 | if ( (NULL != ci->oh) && |
552 | (NULL != h)) | 552 | (NULL != h) ) |
553 | GNUNET_TRANSPORT_offer_hello_cancel (ci->oh); | 553 | GNUNET_TRANSPORT_offer_hello_cancel (ci->oh); |
554 | if (NULL != h) | 554 | if (NULL != h) |
555 | ci->oh = GNUNET_TRANSPORT_offer_hello (GDS_cfg, | 555 | ci->oh = GNUNET_TRANSPORT_offer_hello (GDS_cfg, |
556 | h, | 556 | h, |
557 | &offer_hello_done, | 557 | &offer_hello_done, |
558 | ci); | 558 | ci); |
559 | if ((NULL != ci->sh) && | 559 | if ( (NULL != ci->sh) && |
560 | (ci->strength != strength)) | 560 | (ci->strength != strength) ) |
561 | GNUNET_ATS_connectivity_suggest_cancel (ci->sh); | 561 | GNUNET_ATS_connectivity_suggest_cancel (ci->sh); |
562 | if (ci->strength != strength) | 562 | if (ci->strength != strength) |
563 | { | ||
563 | ci->sh = GNUNET_ATS_connectivity_suggest (ats_ch, | 564 | ci->sh = GNUNET_ATS_connectivity_suggest (ats_ch, |
564 | pid, | 565 | pid, |
565 | strength); | 566 | strength); |
566 | ci->strength = strength; | 567 | ci->strength = strength; |
568 | } | ||
567 | } | 569 | } |
568 | 570 | ||
569 | 571 | ||
@@ -594,9 +596,6 @@ update_desire_strength (void *cls, | |||
594 | 596 | ||
595 | /** | 597 | /** |
596 | * Update our preferences for connectivity as given to ATS. | 598 | * Update our preferences for connectivity as given to ATS. |
597 | * | ||
598 | * @param cls the `struct PeerInfo` of the peer | ||
599 | * @param tc scheduler context. | ||
600 | */ | 599 | */ |
601 | static void | 600 | static void |
602 | update_connect_preferences (void) | 601 | update_connect_preferences (void) |
@@ -608,12 +607,12 @@ update_connect_preferences (void) | |||
608 | 607 | ||
609 | 608 | ||
610 | /** | 609 | /** |
611 | * Add each of the peers we already know to the bloom filter of | 610 | * Add each of the peers we already know to the Bloom filter of |
612 | * the request so that we don't get duplicate HELLOs. | 611 | * the request so that we don't get duplicate HELLOs. |
613 | * | 612 | * |
614 | * @param cls the `struct GNUNET_BLOCK_Group` | 613 | * @param cls the `struct GNUNET_BLOCK_Group` |
615 | * @param key peer identity to add to the bloom filter | 614 | * @param key peer identity to add to the bloom filter |
616 | * @param value value the peer information (unused) | 615 | * @param value the peer information |
617 | * @return #GNUNET_YES (we should continue to iterate) | 616 | * @return #GNUNET_YES (we should continue to iterate) |
618 | */ | 617 | */ |
619 | static enum GNUNET_GenericReturnValue | 618 | static enum GNUNET_GenericReturnValue |
@@ -622,18 +621,13 @@ add_known_to_bloom (void *cls, | |||
622 | void *value) | 621 | void *value) |
623 | { | 622 | { |
624 | struct GNUNET_BLOCK_Group *bg = cls; | 623 | struct GNUNET_BLOCK_Group *bg = cls; |
625 | struct GNUNET_HashCode key_hash; | 624 | struct PeerInfo *pi = value; |
626 | 625 | ||
627 | (void) cls; | ||
628 | (void) value; | ||
629 | GNUNET_CRYPTO_hash (key, | ||
630 | sizeof(struct GNUNET_PeerIdentity), | ||
631 | &key_hash); | ||
632 | GNUNET_BLOCK_group_set_seen (bg, | 626 | GNUNET_BLOCK_group_set_seen (bg, |
633 | &key_hash, | 627 | &pi->phash, |
634 | 1); | 628 | 1); |
635 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 629 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
636 | "Adding known peer (%s) to bloomfilter for FIND PEER\n", | 630 | "Adding known peer (%s) to Bloom filter for FIND PEER\n", |
637 | GNUNET_i2s (key)); | 631 | GNUNET_i2s (key)); |
638 | return GNUNET_YES; | 632 | return GNUNET_YES; |
639 | } | 633 | } |
@@ -644,73 +638,88 @@ add_known_to_bloom (void *cls, | |||
644 | * so that we can find the closest peers in the network to ourselves | 638 | * so that we can find the closest peers in the network to ourselves |
645 | * and attempt to connect to them. | 639 | * and attempt to connect to them. |
646 | * | 640 | * |
647 | * @param cls closure for this task | 641 | * @param cls closure for this task, NULL |
648 | */ | 642 | */ |
649 | static void | 643 | static void |
650 | send_find_peer_message (void *cls) | 644 | send_find_peer_message (void *cls) |
651 | { | 645 | { |
652 | struct GNUNET_TIME_Relative next_send_time; | ||
653 | struct GNUNET_BLOCK_Group *bg; | ||
654 | struct GNUNET_CONTAINER_BloomFilter *peer_bf; | ||
655 | |||
656 | (void) cls; | 646 | (void) cls; |
657 | find_peer_task = NULL; | 647 | |
658 | if (newly_found_peers > bucket_size) | 648 | /* Compute when to do this again (and if we should |
649 | even send a message right now) */ | ||
659 | { | 650 | { |
660 | /* If we are finding many peers already, no need to send out our request right now! */ | 651 | struct GNUNET_TIME_Relative next_send_time; |
652 | bool done_early; | ||
653 | |||
654 | find_peer_task = NULL; | ||
655 | done_early = (newly_found_peers > bucket_size); | ||
656 | /* schedule next round, taking longer if we found more peers | ||
657 | in the last round. */ | ||
658 | next_send_time.rel_value_us = | ||
659 | DHT_MINIMUM_FIND_PEER_INTERVAL.rel_value_us | ||
660 | + GNUNET_CRYPTO_random_u64 ( | ||
661 | GNUNET_CRYPTO_QUALITY_WEAK, | ||
662 | GNUNET_TIME_relative_multiply ( | ||
663 | DHT_AVG_FIND_PEER_INTERVAL, | ||
664 | 100 * (1 + newly_found_peers) / bucket_size).rel_value_us); | ||
665 | newly_found_peers = 0; | ||
666 | GNUNET_assert (NULL == find_peer_task); | ||
661 | find_peer_task = | 667 | find_peer_task = |
662 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, | 668 | GNUNET_SCHEDULER_add_delayed (next_send_time, |
663 | &send_find_peer_message, | 669 | &send_find_peer_message, |
664 | NULL); | 670 | NULL); |
665 | newly_found_peers = 0; | 671 | if (done_early) |
666 | return; | 672 | return; |
673 | } | ||
674 | |||
675 | /* actually send 'find peer' request */ | ||
676 | { | ||
677 | struct GNUNET_BLOCK_Group *bg; | ||
678 | struct GNUNET_CONTAINER_BloomFilter *peer_bf; | ||
679 | |||
680 | bg = GNUNET_BLOCK_group_create (GDS_block_context, | ||
681 | GNUNET_BLOCK_TYPE_DHT_HELLO, | ||
682 | GNUNET_CRYPTO_random_u32 ( | ||
683 | GNUNET_CRYPTO_QUALITY_WEAK, | ||
684 | UINT32_MAX), | ||
685 | NULL, | ||
686 | 0, | ||
687 | "filter-size", | ||
688 | DHT_BLOOM_SIZE, | ||
689 | NULL); | ||
690 | GNUNET_CONTAINER_multipeermap_iterate (all_connected_peers, | ||
691 | &add_known_to_bloom, | ||
692 | bg); | ||
693 | peer_bf | ||
694 | = GNUNET_CONTAINER_bloomfilter_init (NULL, | ||
695 | DHT_BLOOM_SIZE, | ||
696 | GNUNET_CONSTANTS_BLOOMFILTER_K); | ||
697 | if (GNUNET_OK != | ||
698 | GDS_NEIGHBOURS_handle_get (GNUNET_BLOCK_TYPE_DHT_HELLO, | ||
699 | GNUNET_DHT_RO_FIND_PEER | ||
700 | | GNUNET_DHT_RO_RECORD_ROUTE, | ||
701 | FIND_PEER_REPLICATION_LEVEL, | ||
702 | 0, /* hop count */ | ||
703 | &my_identity_hash, | ||
704 | NULL, 0, /* xquery */ | ||
705 | bg, | ||
706 | peer_bf)) | ||
707 | { | ||
708 | GNUNET_STATISTICS_update (GDS_stats, | ||
709 | "# Failed to initiate FIND PEER lookup", | ||
710 | 1, | ||
711 | GNUNET_NO); | ||
712 | } | ||
713 | else | ||
714 | { | ||
715 | GNUNET_STATISTICS_update (GDS_stats, | ||
716 | "# FIND PEER messages initiated", | ||
717 | 1, | ||
718 | GNUNET_NO); | ||
719 | } | ||
720 | GNUNET_CONTAINER_bloomfilter_free (peer_bf); | ||
721 | GNUNET_BLOCK_group_destroy (bg); | ||
667 | } | 722 | } |
668 | bg = GNUNET_BLOCK_group_create (GDS_block_context, | ||
669 | GNUNET_BLOCK_TYPE_DHT_HELLO, | ||
670 | GNUNET_CRYPTO_random_u32 ( | ||
671 | GNUNET_CRYPTO_QUALITY_WEAK, | ||
672 | UINT32_MAX), | ||
673 | NULL, | ||
674 | 0, | ||
675 | "filter-size", | ||
676 | DHT_BLOOM_SIZE, | ||
677 | NULL); | ||
678 | GNUNET_CONTAINER_multipeermap_iterate (all_connected_peers, | ||
679 | &add_known_to_bloom, | ||
680 | bg); | ||
681 | GNUNET_STATISTICS_update (GDS_stats, | ||
682 | "# FIND PEER messages initiated", | ||
683 | 1, | ||
684 | GNUNET_NO); | ||
685 | peer_bf | ||
686 | = GNUNET_CONTAINER_bloomfilter_init (NULL, | ||
687 | DHT_BLOOM_SIZE, | ||
688 | GNUNET_CONSTANTS_BLOOMFILTER_K); | ||
689 | // FIXME: pass priority!? | ||
690 | GDS_NEIGHBOURS_handle_get (GNUNET_BLOCK_TYPE_DHT_HELLO, | ||
691 | GNUNET_DHT_RO_FIND_PEER | ||
692 | | GNUNET_DHT_RO_RECORD_ROUTE, | ||
693 | FIND_PEER_REPLICATION_LEVEL, | ||
694 | 0, | ||
695 | &my_identity_hash, | ||
696 | NULL, | ||
697 | 0, | ||
698 | bg, | ||
699 | peer_bf); | ||
700 | GNUNET_CONTAINER_bloomfilter_free (peer_bf); | ||
701 | GNUNET_BLOCK_group_destroy (bg); | ||
702 | /* schedule next round */ | ||
703 | next_send_time.rel_value_us = | ||
704 | DHT_MINIMUM_FIND_PEER_INTERVAL.rel_value_us | ||
705 | + GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, | ||
706 | DHT_MAXIMUM_FIND_PEER_INTERVAL.rel_value_us | ||
707 | / (newly_found_peers + 1)); | ||
708 | newly_found_peers = 0; | ||
709 | GNUNET_assert (NULL == find_peer_task); | ||
710 | find_peer_task = | ||
711 | GNUNET_SCHEDULER_add_delayed (next_send_time, | ||
712 | &send_find_peer_message, | ||
713 | NULL); | ||
714 | } | 723 | } |
715 | 724 | ||
716 | 725 | ||
@@ -728,6 +737,7 @@ handle_core_connect (void *cls, | |||
728 | struct GNUNET_MQ_Handle *mq) | 737 | struct GNUNET_MQ_Handle *mq) |
729 | { | 738 | { |
730 | struct PeerInfo *pi; | 739 | struct PeerInfo *pi; |
740 | struct PeerBucket *bucket; | ||
731 | 741 | ||
732 | (void) cls; | 742 | (void) cls; |
733 | /* Check for connect to self message */ | 743 | /* Check for connect to self message */ |
@@ -735,13 +745,13 @@ handle_core_connect (void *cls, | |||
735 | peer)) | 745 | peer)) |
736 | return NULL; | 746 | return NULL; |
737 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 747 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
738 | "Connected to %s\n", | 748 | "Connected to peer %s\n", |
739 | GNUNET_i2s (peer)); | 749 | GNUNET_i2s (peer)); |
740 | GNUNET_assert (GNUNET_NO == | 750 | GNUNET_assert (NULL == |
741 | GNUNET_CONTAINER_multipeermap_get (all_connected_peers, | 751 | GNUNET_CONTAINER_multipeermap_get (all_connected_peers, |
742 | peer)); | 752 | peer)); |
743 | GNUNET_STATISTICS_update (GDS_stats, | 753 | GNUNET_STATISTICS_update (GDS_stats, |
744 | gettext_noop ("# peers connected"), | 754 | "# peers connected", |
745 | 1, | 755 | 1, |
746 | GNUNET_NO); | 756 | GNUNET_NO); |
747 | pi = GNUNET_new (struct PeerInfo); | 757 | pi = GNUNET_new (struct PeerInfo); |
@@ -751,27 +761,27 @@ handle_core_connect (void *cls, | |||
751 | sizeof(struct GNUNET_PeerIdentity), | 761 | sizeof(struct GNUNET_PeerIdentity), |
752 | &pi->phash); | 762 | &pi->phash); |
753 | pi->peer_bucket = find_bucket (&pi->phash); | 763 | pi->peer_bucket = find_bucket (&pi->phash); |
754 | GNUNET_assert ((pi->peer_bucket >= 0) && | 764 | GNUNET_assert ( (pi->peer_bucket >= 0) && |
755 | ((unsigned int) pi->peer_bucket < MAX_BUCKETS)); | 765 | ((unsigned int) pi->peer_bucket < MAX_BUCKETS)); |
756 | GNUNET_CONTAINER_DLL_insert_tail (k_buckets[pi->peer_bucket].head, | 766 | bucket = &k_buckets[pi->peer_bucket]; |
757 | k_buckets[pi->peer_bucket].tail, | 767 | GNUNET_CONTAINER_DLL_insert_tail (bucket->head, |
768 | bucket->tail, | ||
758 | pi); | 769 | pi); |
759 | k_buckets[pi->peer_bucket].peers_size++; | 770 | bucket->peers_size++; |
760 | closest_bucket = GNUNET_MAX (closest_bucket, | 771 | closest_bucket = GNUNET_MAX (closest_bucket, |
761 | (unsigned int) pi->peer_bucket); | 772 | (unsigned int) pi->peer_bucket + 1); |
762 | GNUNET_assert (GNUNET_OK == | 773 | GNUNET_assert (GNUNET_OK == |
763 | GNUNET_CONTAINER_multipeermap_put (all_connected_peers, | 774 | GNUNET_CONTAINER_multipeermap_put (all_connected_peers, |
764 | pi->id, | 775 | pi->id, |
765 | pi, | 776 | pi, |
766 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | 777 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); |
767 | if ((pi->peer_bucket > 0) && | 778 | if (bucket->peers_size <= bucket_size) |
768 | (k_buckets[pi->peer_bucket].peers_size <= bucket_size)) | ||
769 | { | 779 | { |
770 | update_connect_preferences (); | 780 | update_connect_preferences (); |
771 | newly_found_peers++; | 781 | newly_found_peers++; |
772 | } | 782 | } |
773 | if ((1 == GNUNET_CONTAINER_multipeermap_size (all_connected_peers)) && | 783 | if ( (1 == GNUNET_CONTAINER_multipeermap_size (all_connected_peers)) && |
774 | (GNUNET_YES != disable_try_connect)) | 784 | (GNUNET_YES != disable_try_connect) ) |
775 | { | 785 | { |
776 | /* got a first connection, good time to start with FIND PEER requests... */ | 786 | /* got a first connection, good time to start with FIND PEER requests... */ |
777 | GNUNET_assert (NULL == find_peer_task); | 787 | GNUNET_assert (NULL == find_peer_task); |
@@ -795,38 +805,40 @@ handle_core_disconnect (void *cls, | |||
795 | void *internal_cls) | 805 | void *internal_cls) |
796 | { | 806 | { |
797 | struct PeerInfo *to_remove = internal_cls; | 807 | struct PeerInfo *to_remove = internal_cls; |
808 | struct PeerBucket *bucket; | ||
798 | 809 | ||
799 | (void) cls; | 810 | (void) cls; |
800 | /* Check for disconnect from self message */ | 811 | /* Check for disconnect from self message (on shutdown) */ |
801 | if (NULL == to_remove) | 812 | if (NULL == to_remove) |
802 | return; | 813 | return; |
803 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 814 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
804 | "Disconnected %s\n", | 815 | "Disconnected from peer %s\n", |
805 | GNUNET_i2s (peer)); | 816 | GNUNET_i2s (peer)); |
806 | GNUNET_STATISTICS_update (GDS_stats, | 817 | GNUNET_STATISTICS_update (GDS_stats, |
807 | gettext_noop ("# peers connected"), | 818 | "# peers connected", |
808 | -1, | 819 | -1, |
809 | GNUNET_NO); | 820 | GNUNET_NO); |
810 | GNUNET_assert (GNUNET_YES == | 821 | GNUNET_assert (GNUNET_YES == |
811 | GNUNET_CONTAINER_multipeermap_remove (all_connected_peers, | 822 | GNUNET_CONTAINER_multipeermap_remove (all_connected_peers, |
812 | peer, | 823 | peer, |
813 | to_remove)); | 824 | to_remove)); |
814 | if ((0 == GNUNET_CONTAINER_multipeermap_size (all_connected_peers)) && | 825 | if ( (0 == GNUNET_CONTAINER_multipeermap_size (all_connected_peers)) && |
815 | (GNUNET_YES != disable_try_connect)) | 826 | (GNUNET_YES != disable_try_connect)) |
816 | { | 827 | { |
817 | GNUNET_SCHEDULER_cancel (find_peer_task); | 828 | GNUNET_SCHEDULER_cancel (find_peer_task); |
818 | find_peer_task = NULL; | 829 | find_peer_task = NULL; |
819 | } | 830 | } |
820 | GNUNET_assert (to_remove->peer_bucket >= 0); | 831 | GNUNET_assert (to_remove->peer_bucket >= 0); |
821 | GNUNET_CONTAINER_DLL_remove (k_buckets[to_remove->peer_bucket].head, | 832 | bucket = &k_buckets[to_remove->peer_bucket]; |
822 | k_buckets[to_remove->peer_bucket].tail, | 833 | GNUNET_CONTAINER_DLL_remove (bucket->head, |
834 | bucket->tail, | ||
823 | to_remove); | 835 | to_remove); |
824 | GNUNET_assert (k_buckets[to_remove->peer_bucket].peers_size > 0); | 836 | GNUNET_assert (bucket->peers_size > 0); |
825 | k_buckets[to_remove->peer_bucket].peers_size--; | 837 | bucket->peers_size--; |
826 | while ((closest_bucket > 0) && | 838 | while ( (closest_bucket > 0) && |
827 | (0 == k_buckets[to_remove->peer_bucket].peers_size)) | 839 | (0 == k_buckets[closest_bucket - 1].peers_size)) |
828 | closest_bucket--; | 840 | closest_bucket--; |
829 | if (k_buckets[to_remove->peer_bucket].peers_size < bucket_size) | 841 | if (bucket->peers_size < bucket_size) |
830 | update_connect_preferences (); | 842 | update_connect_preferences (); |
831 | GNUNET_free (to_remove); | 843 | GNUNET_free (to_remove); |
832 | } | 844 | } |
@@ -856,8 +868,9 @@ get_forward_count (uint32_t hop_count, | |||
856 | { | 868 | { |
857 | /* forcefully terminate */ | 869 | /* forcefully terminate */ |
858 | GNUNET_STATISTICS_update (GDS_stats, | 870 | GNUNET_STATISTICS_update (GDS_stats, |
859 | gettext_noop ("# requests TTL-dropped"), | 871 | "# requests TTL-dropped", |
860 | 1, GNUNET_NO); | 872 | 1, |
873 | GNUNET_NO); | ||
861 | return 0; | 874 | return 0; |
862 | } | 875 | } |
863 | if (hop_count > GDS_NSE_get () * 2.0) | 876 | if (hop_count > GDS_NSE_get () * 2.0) |
@@ -879,8 +892,8 @@ get_forward_count (uint32_t hop_count, | |||
879 | forward_count = (uint32_t) target_value; | 892 | forward_count = (uint32_t) target_value; |
880 | /* Subtract forward_count (floor) from target_value (yields value between 0 and 1) */ | 893 | /* Subtract forward_count (floor) from target_value (yields value between 0 and 1) */ |
881 | target_value = target_value - forward_count; | 894 | target_value = target_value - forward_count; |
882 | random_value = | 895 | random_value = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, |
883 | GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX); | 896 | UINT32_MAX); |
884 | if (random_value < (target_value * UINT32_MAX)) | 897 | if (random_value < (target_value * UINT32_MAX)) |
885 | forward_count++; | 898 | forward_count++; |
886 | return GNUNET_MIN (forward_count, | 899 | return GNUNET_MIN (forward_count, |
@@ -964,7 +977,7 @@ select_peer (const struct GNUNET_HashCode *key, | |||
964 | uint64_t best_in_bucket = UINT64_MAX; | 977 | uint64_t best_in_bucket = UINT64_MAX; |
965 | 978 | ||
966 | chosen = NULL; | 979 | chosen = NULL; |
967 | for (bc = 0; bc <= closest_bucket; bc++) | 980 | for (bc = 0; bc < closest_bucket; bc++) |
968 | { | 981 | { |
969 | count = 0; | 982 | count = 0; |
970 | for (pos = k_buckets[bc].head; | 983 | for (pos = k_buckets[bc].head; |
@@ -1027,7 +1040,7 @@ select_peer (const struct GNUNET_HashCode *key, | |||
1027 | /* select "random" peer */ | 1040 | /* select "random" peer */ |
1028 | /* count number of peers that are available and not filtered */ | 1041 | /* count number of peers that are available and not filtered */ |
1029 | count = 0; | 1042 | count = 0; |
1030 | for (bc = 0; bc <= closest_bucket; bc++) | 1043 | for (bc = 0; bc < closest_bucket; bc++) |
1031 | { | 1044 | { |
1032 | pos = k_buckets[bc].head; | 1045 | pos = k_buckets[bc].head; |
1033 | while ((NULL != pos) && (count < bucket_size)) | 1046 | while ((NULL != pos) && (count < bucket_size)) |
@@ -1064,7 +1077,7 @@ select_peer (const struct GNUNET_HashCode *key, | |||
1064 | selected = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, | 1077 | selected = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, |
1065 | count); | 1078 | count); |
1066 | count = 0; | 1079 | count = 0; |
1067 | for (bc = 0; bc <= closest_bucket; bc++) | 1080 | for (bc = 0; bc < closest_bucket; bc++) |
1068 | { | 1081 | { |
1069 | for (pos = k_buckets[bc].head; ((pos != NULL) && (count < bucket_size)); | 1082 | for (pos = k_buckets[bc].head; ((pos != NULL) && (count < bucket_size)); |
1070 | pos = pos->next) | 1083 | pos = pos->next) |
@@ -1789,9 +1802,9 @@ handle_find_peer (const struct GNUNET_PeerIdentity *sender, | |||
1789 | if (0 == | 1802 | if (0 == |
1790 | GNUNET_memcmp (&my_identity_hash, | 1803 | GNUNET_memcmp (&my_identity_hash, |
1791 | query_hash)) | 1804 | query_hash)) |
1792 | bucket_idx = closest_bucket; | 1805 | bucket_idx = closest_bucket - 1; |
1793 | else | 1806 | else |
1794 | bucket_idx = GNUNET_MIN ((int) closest_bucket, | 1807 | bucket_idx = GNUNET_MIN ((int) closest_bucket - 1, |
1795 | find_bucket (query_hash)); | 1808 | find_bucket (query_hash)); |
1796 | if (bucket_idx < 0) | 1809 | if (bucket_idx < 0) |
1797 | return; | 1810 | return; |