diff --git a/include/libtorrent/kademlia/routing_table.hpp b/include/libtorrent/kademlia/routing_table.hpp index 29d767f69..d6171dafd 100644 --- a/include/libtorrent/kademlia/routing_table.hpp +++ b/include/libtorrent/kademlia/routing_table.hpp @@ -187,6 +187,8 @@ public: void check_invariant() const; #endif + bool is_full(int bucket) const; + private: dht_logger* m_log; diff --git a/src/kademlia/node.cpp b/src/kademlia/node.cpp index 964f4cf5e..c976c4ca3 100644 --- a/src/kademlia/node.cpp +++ b/src/kademlia/node.cpp @@ -564,14 +564,21 @@ void node::send_single_refresh(udp::endpoint const& ep, int bucket e["y"] = "q"; entry& a = e["a"]; - // use get_peers instead of find_node. We'll get nodes in the response - // either way. - e["q"] = "get_peers"; - a["info_hash"] = target.to_string(); - m_counters.inc_stats_counter(counters::dht_get_peers_out); + if (m_table.is_full(bucket)) + { + // current bucket is full, just ping it. + e["q"] = "ping"; + m_counters.inc_stats_counter(counters::dht_ping_out); + } + else + { + // use get_peers instead of find_node. We'll get nodes in the response + // either way. + e["q"] = "get_peers"; + a["info_hash"] = target.to_string(); + m_counters.inc_stats_counter(counters::dht_get_peers_out); + } -// e["q"] = "find_node"; -// a["target"] = target.to_string(); m_rpc.invoke(e, ep, o); } diff --git a/src/kademlia/routing_table.cpp b/src/kademlia/routing_table.cpp index e3b38ded8..84caecfbc 100644 --- a/src/kademlia/routing_table.cpp +++ b/src/kademlia/routing_table.cpp @@ -1235,5 +1235,17 @@ void routing_table::check_invariant() const } #endif +bool routing_table::is_full(int bucket) const +{ + int num_buckets = m_buckets.size(); + if (num_buckets == 0) return false; + if (bucket >= num_buckets) return false; + + table_t::const_iterator i = m_buckets.begin(); + std::advance(i, bucket); + return (i->live_nodes.size() >= bucket_limit(bucket) + && i->replacements.size() >= m_bucket_size); +} + } } // namespace libtorrent::dht