fix issue with obfuscated_get_peers where peers in responses to obfuscated requests would still be returned. slight refactoring to move traversal algorithm level logic to traversal_observer class

This commit is contained in:
Arvid Norberg 2013-12-14 23:25:38 +00:00
parent 9aac6b4d23
commit 93d7d89ced
5 changed files with 110 additions and 48 deletions

View File

@ -59,7 +59,7 @@ class node_impl;
//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
struct find_data : traversal_algorithm
{
public:
typedef boost::function<void(std::vector<tcp::endpoint> const&)> data_callback;
@ -83,7 +83,8 @@ public:
protected:
virtual void done();
observer_ptr new_observer(void* ptr, udp::endpoint const& ep, node_id const& id);
observer_ptr new_observer(void* ptr, udp::endpoint const& ep
, node_id const& id);
virtual bool invoke(observer_ptr o);
data_callback m_data_callback;
@ -95,9 +96,8 @@ protected:
bool m_noseeds:1;
};
class obfuscated_get_peers : public find_data
struct obfuscated_get_peers : find_data
{
public:
typedef find_data::nodes_callback done_callback;
obfuscated_get_peers(node_impl& node, node_id target
@ -109,7 +109,8 @@ public:
protected:
observer_ptr new_observer(void* ptr, udp::endpoint const& ep, node_id const& id);
observer_ptr new_observer(void* ptr, udp::endpoint const& ep
, node_id const& id);
virtual bool invoke(observer_ptr o);
virtual void done();
private:
@ -118,13 +119,22 @@ private:
bool m_obfuscated;
};
class find_data_observer : public observer
struct find_data_observer : traversal_observer
{
public:
find_data_observer(
boost::intrusive_ptr<traversal_algorithm> const& algorithm
, udp::endpoint const& ep, node_id const& id)
: observer(algorithm, ep, id)
: traversal_observer(algorithm, ep, id)
{}
void reply(msg const&);
};
struct obfuscated_find_data_observer : traversal_observer
{
obfuscated_find_data_observer(
boost::intrusive_ptr<traversal_algorithm> const& algorithm
, udp::endpoint const& ep, node_id const& id)
: traversal_observer(algorithm, ep, id)
{}
void reply(msg const&);
};

View File

@ -55,7 +55,8 @@ public:
protected:
observer_ptr new_observer(void* ptr, udp::endpoint const& ep, node_id const& id);
observer_ptr new_observer(void* ptr, udp::endpoint const& ep
, node_id const& id);
virtual bool invoke(observer_ptr o);
};

View File

@ -121,6 +121,18 @@ protected:
int m_num_target_nodes;
};
struct traversal_observer : observer
{
traversal_observer(
boost::intrusive_ptr<traversal_algorithm> const& algorithm
, udp::endpoint const& ep, node_id const& id)
: observer(algorithm, ep, id)
{}
// parses out "nodes" and keeps traversing
void reply(msg const&);
};
} } // namespace libtorrent::dht
#endif // TRAVERSAL_ALGORITHM_050324_HPP

View File

@ -122,44 +122,35 @@ void find_data_observer::reply(msg const& m)
static_cast<find_data*>(m_algorithm.get())->got_peers(peer_list);
}
// look for nodes
n = r->dict_find_string("nodes");
if (n)
traversal_observer::reply(m);
done();
}
void obfuscated_find_data_observer::reply(msg const& m)
{
lazy_entry const* r = m.message.dict_find_dict("r");
if (!r)
{
std::vector<node_entry> node_list;
char const* nodes = n->string_ptr();
char const* end = nodes + n->string_length();
while (end - nodes >= 26)
{
node_id id;
std::copy(nodes, nodes + 20, id.begin());
nodes += 20;
m_algorithm->traverse(id, read_v4_endpoint<udp::endpoint>(nodes));
}
}
n = r->dict_find_list("nodes2");
if (n)
{
for (int i = 0; i < n->list_size(); ++i)
{
lazy_entry const* p = n->list_at(0);
if (p->type() != lazy_entry::string_t) continue;
if (p->string_length() < 6 + 20) continue;
char const* in = p->string_ptr();
node_id id;
std::copy(in, in + 20, id.begin());
in += 20;
if (p->string_length() == 6 + 20)
m_algorithm->traverse(id, read_v4_endpoint<udp::endpoint>(in));
#if TORRENT_USE_IPV6
else if (p->string_length() == 18 + 20)
m_algorithm->traverse(id, read_v6_endpoint<udp::endpoint>(in));
#ifdef TORRENT_DHT_VERBOSE_LOGGING
TORRENT_LOG(traversal) << "[" << m_algorithm.get()
<< "] missing response dict";
#endif
}
return;
}
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;
}
traversal_observer::reply(m);
done();
}
@ -271,16 +262,28 @@ obfuscated_get_peers::obfuscated_get_peers(
{
}
char const* obfuscated_get_peers::name() const { return !m_obfuscated ? find_data::name() : "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)
{
observer_ptr o(new (ptr) find_data_observer(this, ep, id));
if (m_obfuscated)
{
observer_ptr o(new (ptr) obfuscated_find_data_observer(this, ep, id));
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS
o->m_in_constructor = false;
o->m_in_constructor = false;
#endif
return o;
return o;
}
else
{
observer_ptr o(new (ptr) find_data_observer(this, ep, id));
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS
o->m_in_constructor = false;
#endif
return o;
}
}
bool obfuscated_get_peers::invoke(observer_ptr o)

View File

@ -40,6 +40,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include <libtorrent/kademlia/node.hpp>
#include <libtorrent/session_status.hpp>
#include "libtorrent/broadcast_socket.hpp" // for cidr_distance
#include <libtorrent/socket_io.hpp> // for read_*_endpoint
#include <boost/bind.hpp>
@ -49,6 +50,11 @@ namespace libtorrent { namespace dht
TORRENT_DEFINE_LOG(traversal)
#endif
using detail::read_v4_endpoint;
#if TORRENT_USE_IPV6
using detail::read_v6_endpoint;
#endif
observer_ptr traversal_algorithm::new_observer(void* ptr
, udp::endpoint const& ep, node_id const& id)
{
@ -464,5 +470,35 @@ void traversal_algorithm::status(dht_lookup& l)
l.last_sent = last_sent;
}
void traversal_observer::reply(msg const& m)
{
lazy_entry const* r = m.message.dict_find_dict("r");
if (!r)
{
#ifdef TORRENT_DHT_VERBOSE_LOGGING
TORRENT_LOG(traversal) << "[" << m_algorithm.get()
<< "] missing response dict";
#endif
return;
}
// look for nodes
lazy_entry const* n = r->dict_find_string("nodes");
if (n)
{
std::vector<node_entry> node_list;
char const* nodes = n->string_ptr();
char const* end = nodes + n->string_length();
while (end - nodes >= 26)
{
node_id id;
std::copy(nodes, nodes + 20, id.begin());
nodes += 20;
m_algorithm->traverse(id, read_v4_endpoint<udp::endpoint>(nodes));
}
}
}
} } // namespace libtorrent::dht