reorder the node-list in the DHT traversal algorithm if a node updates its ID
This commit is contained in:
parent
fd26cc026b
commit
0e04ab8d72
|
@ -115,7 +115,7 @@ struct observer : boost::noncopyable
|
|||
address target_addr() const;
|
||||
udp::endpoint target_ep() const;
|
||||
|
||||
void set_id(node_id const& id) { m_id = id; }
|
||||
void set_id(node_id const& id);
|
||||
node_id const& id() const { return m_id; }
|
||||
|
||||
void set_transaction_id(boost::uint16_t tid)
|
||||
|
|
|
@ -77,6 +77,7 @@ struct traversal_algorithm : boost::noncopyable
|
|||
|
||||
node_id const& target() const { return m_target; }
|
||||
|
||||
void resort_results();
|
||||
void add_entry(node_id const& id, udp::endpoint addr, unsigned char flags);
|
||||
|
||||
traversal_algorithm(node_impl& node, node_id target);
|
||||
|
|
|
@ -80,10 +80,6 @@ void find_data_observer::reply(msg const& m)
|
|||
node_id(id->string_ptr()), token->string_value());
|
||||
}
|
||||
|
||||
// in case we didn't know the id of this peer when we sent the message to
|
||||
// it. For instance if it's a bootstrap node.
|
||||
set_id(node_id(id->string_ptr()));
|
||||
|
||||
traversal_observer::reply(m);
|
||||
done();
|
||||
}
|
||||
|
|
|
@ -151,6 +151,13 @@ void observer::timeout()
|
|||
m_algorithm->failed(observer_ptr(this));
|
||||
}
|
||||
|
||||
void observer::set_id(node_id const& id)
|
||||
{
|
||||
if (m_id == id) return;
|
||||
m_id = id;
|
||||
if (m_algorithm) m_algorithm->resort_results();
|
||||
}
|
||||
|
||||
enum { observer_size = max3<
|
||||
sizeof(find_data_observer)
|
||||
, sizeof(announce_observer)
|
||||
|
|
|
@ -42,6 +42,10 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/broadcast_socket.hpp" // for cidr_distance
|
||||
#include <libtorrent/socket_io.hpp> // for read_*_endpoint
|
||||
|
||||
#if TORRENT_USE_ASSERTS
|
||||
#include <boost/algorithm/cxx11/is_sorted.hpp> // for is_sorted
|
||||
#endif
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
namespace libtorrent { namespace dht
|
||||
|
@ -100,6 +104,20 @@ bool compare_ip_cidr(observer_ptr const& lhs, observer_ptr const& rhs)
|
|||
return dist <= cutoff;
|
||||
}
|
||||
|
||||
void traversal_algorithm::resort_results()
|
||||
{
|
||||
std::sort(
|
||||
m_results.begin()
|
||||
, m_results.end()
|
||||
, boost::bind(
|
||||
compare_ref
|
||||
, boost::bind(&observer::id, _1)
|
||||
, boost::bind(&observer::id, _2)
|
||||
, m_target
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
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));
|
||||
|
@ -121,6 +139,14 @@ void traversal_algorithm::add_entry(node_id const& id, udp::endpoint addr, unsig
|
|||
|
||||
o->flags |= flags;
|
||||
|
||||
TORRENT_ASSERT(boost::algorithm::is_sorted(m_results.begin(), m_results.end()
|
||||
, boost::bind(
|
||||
compare_ref
|
||||
, boost::bind(&observer::id, _1)
|
||||
, boost::bind(&observer::id, _2)
|
||||
, m_target)
|
||||
));
|
||||
|
||||
std::vector<observer_ptr>::iterator i = std::lower_bound(
|
||||
m_results.begin()
|
||||
, m_results.end()
|
||||
|
@ -172,6 +198,14 @@ void traversal_algorithm::add_entry(node_id const& id, udp::endpoint addr, unsig
|
|||
;
|
||||
#endif
|
||||
i = m_results.insert(i, o);
|
||||
|
||||
TORRENT_ASSERT(boost::algorithm::is_sorted(m_results.begin(), m_results.end()
|
||||
, boost::bind(
|
||||
compare_ref
|
||||
, boost::bind(&observer::id, _1)
|
||||
, boost::bind(&observer::id, _2)
|
||||
, m_target)
|
||||
));
|
||||
}
|
||||
|
||||
if (m_results.size() > 100)
|
||||
|
@ -512,6 +546,19 @@ void traversal_observer::reply(msg const& m)
|
|||
m_algorithm->traverse(id, read_v4_endpoint<udp::endpoint>(nodes));
|
||||
}
|
||||
}
|
||||
|
||||
lazy_entry const* id = r->dict_find_string("id");
|
||||
if (!id || id->string_length() != 20)
|
||||
{
|
||||
#ifdef TORRENT_DHT_VERBOSE_LOGGING
|
||||
TORRENT_LOG(traversal) << "[" << m_algorithm.get() << "] invalid id in response";
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
// in case we didn't know the id of this peer when we sent the message to
|
||||
// it. For instance if it's a bootstrap node.
|
||||
set_id(node_id(id->string_ptr()));
|
||||
}
|
||||
|
||||
void traversal_algorithm::abort()
|
||||
|
|
Loading…
Reference in New Issue