diff --git a/include/libtorrent/kademlia/traversal_algorithm.hpp b/include/libtorrent/kademlia/traversal_algorithm.hpp index b09601747..0bc50bfc9 100644 --- a/include/libtorrent/kademlia/traversal_algorithm.hpp +++ b/include/libtorrent/kademlia/traversal_algorithm.hpp @@ -78,21 +78,7 @@ struct traversal_algorithm : boost::noncopyable void add_entry(node_id const& id, udp::endpoint addr, unsigned char flags); - traversal_algorithm( - node_impl& node - , node_id target) - : m_ref_count(0) - , m_node(node) - , m_target(target) - , m_invoke_count(0) - , m_branch_factor(3) - , m_responses(0) - , m_timeouts(0) - { -#ifdef TORRENT_DHT_VERBOSE_LOGGING - TORRENT_LOG(traversal) << " [" << this << "] new traversal process. Target: " << target; -#endif - } + traversal_algorithm(node_impl& node, node_id target); protected: @@ -128,6 +114,7 @@ protected: int m_branch_factor; int m_responses; int m_timeouts; + int m_num_target_nodes; }; } } // namespace libtorrent::dht diff --git a/src/kademlia/node.cpp b/src/kademlia/node.cpp index 4acc02b07..7313c9f1a 100644 --- a/src/kademlia/node.cpp +++ b/src/kademlia/node.cpp @@ -433,7 +433,7 @@ time_duration node_impl::connection_timeout() { time_duration d = m_rpc.tick(); ptime now(time_now()); - if (now - m_last_tracker_tick < minutes(10)) return d; + if (now - m_last_tracker_tick < minutes(2)) return d; m_last_tracker_tick = now; // look through all peers and see if any have timed out diff --git a/src/kademlia/refresh.cpp b/src/kademlia/refresh.cpp index fda33f0c3..33d8bf2bc 100644 --- a/src/kademlia/refresh.cpp +++ b/src/kademlia/refresh.cpp @@ -85,6 +85,9 @@ bootstrap::bootstrap( , done_callback const& callback) : refresh(node, target, callback) { + // make it more resilient to nodes not responding. + // we don't want to terminate early when we're bootstrapping + m_num_target_nodes *= 2; } char const* bootstrap::name() const { return "bootstrap"; } diff --git a/src/kademlia/routing_table.cpp b/src/kademlia/routing_table.cpp index 531f22eb3..76e68e901 100644 --- a/src/kademlia/routing_table.cpp +++ b/src/kademlia/routing_table.cpp @@ -183,8 +183,8 @@ void routing_table::touch_bucket(node_id const& target) bool compare_bucket_refresh(routing_table_node const& lhs, routing_table_node const& rhs) { // add the number of nodes to prioritize buckets with few nodes in them - return lhs.last_active + seconds(lhs.live_nodes.size()) - < rhs.last_active + seconds(rhs.live_nodes.size()); + return lhs.last_active + seconds(lhs.live_nodes.size() * 5) + < rhs.last_active + seconds(rhs.live_nodes.size() * 5); } bool routing_table::need_refresh(node_id& target) const @@ -425,15 +425,29 @@ bool routing_table::add_node(node_entry const& e) new_bucket.push_back(*j); j = b.erase(j); } + + // split the replacement bucket as well. If the live bucket + // is not full anymore, also move the replacement entries + // into the main bucket for (bucket_t::iterator j = rb.begin(); j != rb.end();) { if (distance_exp(m_id, j->id) >= 159 - bucket_index) { - ++j; - continue; + if (b.size() >= m_bucket_size) + { + ++j; + continue; + } + b.push_back(*j); + } + else + { + // this entry belongs in the new bucket + if (new_bucket.size() < m_bucket_size) + new_bucket.push_back(*j); + else + new_replacement_bucket.push_back(*j); } - // this entry belongs in the new bucket - new_replacement_bucket.push_back(*j); j = rb.erase(j); } diff --git a/src/kademlia/traversal_algorithm.cpp b/src/kademlia/traversal_algorithm.cpp index 96befd7a3..ebd062575 100644 --- a/src/kademlia/traversal_algorithm.cpp +++ b/src/kademlia/traversal_algorithm.cpp @@ -58,6 +58,23 @@ observer_ptr traversal_algorithm::new_observer(void* ptr return o; } +traversal_algorithm::traversal_algorithm( + node_impl& node + , node_id target) + : m_ref_count(0) + , m_node(node) + , m_target(target) + , m_invoke_count(0) + , m_branch_factor(3) + , m_responses(0) + , m_timeouts(0) + , m_num_target_nodes(m_node.m_table.bucket_size() * 2) +{ +#ifdef TORRENT_DHT_VERBOSE_LOGGING + TORRENT_LOG(traversal) << " [" << this << "] new traversal process. Target: " << target; +#endif +} + void traversal_algorithm::add_entry(node_id const& id, udp::endpoint addr, unsigned char flags) { TORRENT_ASSERT(m_node.m_rpc.allocation_size() >= sizeof(find_data_observer)); @@ -237,7 +254,7 @@ namespace void traversal_algorithm::add_requests() { - int results_target = m_node.m_table.bucket_size(); + int results_target = m_num_target_nodes; // Find the first node that hasn't already been queried. for (std::vector::iterator i = m_results.begin()