improve obfuscated get_peers
This commit is contained in:
parent
9e610dca46
commit
1d55894bef
|
@ -57,7 +57,7 @@ class node_impl;
|
|||
|
||||
// -------- find data -----------
|
||||
|
||||
//TODO: 3 rename this class to find_peers, since that's what it does
|
||||
//TODO: 3 rename this class to get_peers, since that's what it does
|
||||
// find_data is an unnecessarily generic name
|
||||
class find_data : public traversal_algorithm
|
||||
{
|
||||
|
@ -112,6 +112,10 @@ protected:
|
|||
observer_ptr new_observer(void* ptr, udp::endpoint const& ep, node_id const& id);
|
||||
virtual bool invoke(observer_ptr o);
|
||||
virtual void done();
|
||||
private:
|
||||
// when set to false, we no longer obfuscate
|
||||
// the target hash, and send regular get_peers
|
||||
bool m_obfuscated;
|
||||
};
|
||||
|
||||
class find_data_observer : public observer
|
||||
|
|
|
@ -146,6 +146,11 @@ public:
|
|||
|
||||
boost::tuple<int, int> size() const;
|
||||
size_type num_global_nodes() const;
|
||||
|
||||
// the number of bits down we have full buckets
|
||||
// i.e. essentially the number of full buckets
|
||||
// we have
|
||||
int depth() const;
|
||||
|
||||
// returns true if there are no working nodes
|
||||
// in the routing table
|
||||
|
|
|
@ -267,10 +267,11 @@ obfuscated_get_peers::obfuscated_get_peers(
|
|||
, nodes_callback const& ncallback
|
||||
, bool noseeds)
|
||||
: find_data(node, info_hash, dcallback, ncallback, noseeds)
|
||||
, m_obfuscated(true)
|
||||
{
|
||||
}
|
||||
|
||||
char const* obfuscated_get_peers::name() const { return "get_peers [obfuscated]"; }
|
||||
char const* obfuscated_get_peers::name() const { return !m_obfuscated ? find_data::name() : "get_peers [obfuscated]"; }
|
||||
|
||||
observer_ptr obfuscated_get_peers::new_observer(void* ptr
|
||||
, udp::endpoint const& ep, node_id const& id)
|
||||
|
@ -284,6 +285,34 @@ observer_ptr obfuscated_get_peers::new_observer(void* ptr
|
|||
|
||||
bool obfuscated_get_peers::invoke(observer_ptr o)
|
||||
{
|
||||
if (!m_obfuscated) return find_data::invoke(o);
|
||||
|
||||
node_id id = o->id();
|
||||
int shared_prefix = 160 - distance_exp(id, m_target);
|
||||
|
||||
// when we get close to the target zone in the DHT
|
||||
// start using the correct info-hash, in order to
|
||||
// start receiving peers
|
||||
if (shared_prefix > m_node.m_table.depth() - 10)
|
||||
{
|
||||
m_obfuscated = false;
|
||||
// clear the queried bits on all successful nodes in
|
||||
// our node-list for this traversal algorithm, to
|
||||
// allow the get_peers traversal to regress in case
|
||||
// nodes further down end up being dead
|
||||
for (std::vector<observer_ptr>::iterator i = m_results.begin()
|
||||
, end(m_results.end()); i != end; ++i)
|
||||
{
|
||||
observer* o = i->get();
|
||||
// don't re-request from nodes that didn't respond
|
||||
if (o->flags & observer::flag_failed) continue;
|
||||
// don't interrupt with queries that are already in-flight
|
||||
if ((o->flags & observer::flag_alive) == 0) continue;
|
||||
o->flags &= ~(observer::flag_queried | observer::flag_alive);
|
||||
}
|
||||
return find_data::invoke(o);
|
||||
}
|
||||
|
||||
entry e;
|
||||
e["y"] = "q";
|
||||
e["q"] = "find_node";
|
||||
|
@ -295,9 +324,6 @@ bool obfuscated_get_peers::invoke(observer_ptr o)
|
|||
// bits in the info-hash for the node we're querying to
|
||||
// give a good answer, but not more.
|
||||
|
||||
node_id id = o->id();
|
||||
int shared_prefix = 160 - distance_exp(id, m_target);
|
||||
|
||||
// now, obfuscate the bits past shared_prefix + 5
|
||||
node_id obfuscated_target = generate_random_id();
|
||||
obfuscated_target >>= shared_prefix + 3;
|
||||
|
@ -309,6 +335,11 @@ bool obfuscated_get_peers::invoke(observer_ptr o)
|
|||
|
||||
void obfuscated_get_peers::done()
|
||||
{
|
||||
if (!m_obfuscated) return find_data::done();
|
||||
|
||||
// oops, we failed to switch over to the non-obfuscated
|
||||
// mode early enough. do it now
|
||||
|
||||
boost::intrusive_ptr<find_data> ta(new find_data(m_node, m_target
|
||||
, m_data_callback
|
||||
, m_nodes_callback
|
||||
|
@ -327,11 +358,11 @@ void obfuscated_get_peers::done()
|
|||
|
||||
int num_added = 0;
|
||||
for (std::vector<observer_ptr>::iterator i = m_results.begin()
|
||||
, end(m_results.end()); i != end && num_added < 10; ++i)
|
||||
, end(m_results.end()); i != end && num_added < 16; ++i)
|
||||
{
|
||||
observer_ptr o = *i;
|
||||
|
||||
// only add nodes whose node ID we knoe and that
|
||||
// only add nodes whose node ID we know and that
|
||||
// we know are alive
|
||||
if (o->flags & observer::flag_no_id) continue;
|
||||
if ((o->flags & observer::flag_alive) == 0) continue;
|
||||
|
|
|
@ -126,6 +126,21 @@ size_type routing_table::num_global_nodes() const
|
|||
else return (size_type(2) << deepest_bucket) * deepest_size;
|
||||
}
|
||||
|
||||
int routing_table::depth() const
|
||||
{
|
||||
// TODO: 3 cache the depth!
|
||||
int deepest_bucket = 0;
|
||||
for (table_t::const_iterator i = m_buckets.begin()
|
||||
, end(m_buckets.end()); i != end; ++i)
|
||||
{
|
||||
if (i->live_nodes.size() < m_bucket_size)
|
||||
break;
|
||||
// this bucket is full
|
||||
++deepest_bucket;
|
||||
}
|
||||
return deepest_bucket;
|
||||
}
|
||||
|
||||
#if (defined TORRENT_DHT_VERBOSE_LOGGING || defined TORRENT_DEBUG) && TORRENT_USE_IOSTREAM
|
||||
|
||||
void routing_table::print_state(std::ostream& os) const
|
||||
|
|
Loading…
Reference in New Issue