merged DHT change from RC_0_16

This commit is contained in:
Arvid Norberg 2013-10-13 23:04:40 +00:00
parent b7ae64fd1f
commit 50f051433a
8 changed files with 76 additions and 55 deletions

View File

@ -137,15 +137,21 @@ bootstrapping
-------------
In order to set ones initial node ID, the external IP needs to be known. This
is not a trivial problem. With this extension, *all* DHT requests whose node
ID does not match its IP address MUST be serviced and MUST also include one
extra result value (inside the ``r`` dictionary) called ``ip``. The IP field
contains the raw (big endian) byte representation of the external IP address.
This is the same byte sequence used to verify the node ID.
is not a trivial problem. With this extension, *all* DHT responses SHOULD include
a *top-level* field called ``ip``, containing a compact binary representation of
the requestor's IP and port. That is big endian IP followed by 2 bytes of big endian
port.
The IP portion is the same byte sequence used to verify the node ID.
It is important that the ``ip`` field is in the top level dictionary. Nodes that
enforce the node-ID will respond with an error message ("y": "e", "e": { ... }),
whereas a node that supports this extension but without enforcing it will respond
with a normal reply ("y": "r", "r": { ... }).
A DHT node which receives an ``ip`` result in a request SHOULD consider restarting
its DHT node with a new node ID, taking this IP into account. Since a single node
can not be trusted, there should be some mechanism of determining whether or
can not be trusted, there should be some mechanism to determine whether or
not the node has a correct understanding of its external IP or not. This could
be done by voting, or only restart the DHT once at least a certain number of
nodes, from separate searches, tells you your node ID is incorrect.

View File

@ -68,6 +68,7 @@ TORRENT_DECLARE_LOG(node);
#endif
struct traversal_algorithm;
struct dht_observer;
struct key_desc_t
{
@ -295,6 +296,8 @@ public:
rpc_manager m_rpc;
private:
dht_observer* m_observer;
table_t m_map;
dht_immutable_table_t m_immutable_table;
dht_mutable_table_t m_mutable_table;

View File

@ -66,16 +66,13 @@ struct null_observer : public observer
};
class routing_table;
struct dht_observer;
class TORRENT_EXTRA_EXPORT rpc_manager
{
public:
typedef boost::function3<void, address, int, address> external_ip_fun;
rpc_manager(node_id const& our_id
, routing_table& table, udp_socket_interface* sock
, dht_observer* observer);
, routing_table& table, udp_socket_interface* sock);
~rpc_manager();
void unreachable(udp::endpoint const& ep);
@ -118,7 +115,6 @@ private:
node_id m_random_number;
int m_allocated_observers;
bool m_destructing;
dht_observer* m_observer;
};
} } // namespace libtorrent::dht

View File

@ -47,6 +47,7 @@ namespace libtorrent
TORRENT_EXTRA_EXPORT std::string print_endpoint(tcp::endpoint const& ep);
TORRENT_EXTRA_EXPORT std::string print_endpoint(udp::endpoint const& ep);
TORRENT_EXTRA_EXPORT std::string address_to_bytes(address const& a);
TORRENT_EXPORT std::string endpoint_to_bytes(udp::endpoint const& ep);
TORRENT_EXTRA_EXPORT void hash_address(address const& ip, sha1_hash& h);
namespace detail

View File

@ -48,6 +48,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/kademlia/rpc_manager.hpp"
#include "libtorrent/kademlia/routing_table.hpp"
#include "libtorrent/kademlia/node.hpp"
#include <libtorrent/kademlia/dht_observer.hpp>
#include "libtorrent/kademlia/refresh.hpp"
#include "libtorrent/kademlia/find_data.hpp"
@ -100,7 +101,8 @@ node_impl::node_impl(alert_dispatcher* alert_disp
: m_settings(settings)
, m_id(nid == (node_id::min)() || !verify_id(nid, external_address) ? generate_id(external_address) : nid)
, m_table(m_id, 8, settings)
, m_rpc(m_id, m_table, sock, observer)
, m_rpc(m_id, m_table, sock)
, m_observer(observer)
, m_last_tracker_tick(time_now())
, m_post_alert(alert_disp)
, m_sock(sock)
@ -221,6 +223,28 @@ void node_impl::incoming(msg const& m)
char y = *(y_ent->string_ptr());
lazy_entry const* ext_ip = m.message.dict_find_string("ip");
if (ext_ip && ext_ip->string_length() == 4)
{
// this node claims we use the wrong node-ID!
address_v4::bytes_type b;
memcpy(&b[0], ext_ip->string_ptr(), 4);
if (m_observer)
m_observer->set_external_address(address_v4(b)
, m.addr.address());
}
#if TORRENT_USE_IPV6
else if (ext_ip && ext_ip->string_length() == 16)
{
// this node claims we use the wrong node-ID!
address_v6::bytes_type b;
memcpy(&b[0], ext_ip->string_ptr(), 16);
if (m_observer)
m_observer->set_external_address(address_v6(b)
, m.addr.address());
}
#endif
switch (y)
{
case 'r':
@ -657,6 +681,17 @@ void node_impl::incoming_request(msg const& m, entry& e)
return;
}
e["ip"] = endpoint_to_bytes(m.addr);
/*
// if this nodes ID doesn't match its IP, tell it what
// its IP is with an error
// don't enforce this yet
if (!verify_id(id, m.addr.address()))
{
incoming_error(e, "invalid node ID");
return;
}
*/
char const* query = top_level[0]->string_cstr();
lazy_entry const* arg_ent = top_level[1];
@ -668,11 +703,6 @@ void node_impl::incoming_request(msg const& m, entry& e)
entry& reply = e["r"];
m_rpc.add_our_id(reply);
// if this nodes ID doesn't match its IP, tell it what
// its IP is
if (!verify_id(id, m.addr.address()))
reply["ip"] = address_to_bytes(m.addr.address());
// mirror back the other node's external port
reply["p"] = m.addr.port();

View File

@ -46,7 +46,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include <libtorrent/kademlia/refresh.hpp>
#include <libtorrent/kademlia/node.hpp>
#include <libtorrent/kademlia/observer.hpp>
#include <libtorrent/kademlia/dht_observer.hpp>
#include <libtorrent/hasher.hpp>
#include <libtorrent/time.hpp>
#include <time.h> // time()
@ -159,8 +158,7 @@ enum { observer_size = max3<
};
rpc_manager::rpc_manager(node_id const& our_id
, routing_table& table, udp_socket_interface* sock
, dht_observer* observer)
, routing_table& table, udp_socket_interface* sock)
: m_pool_allocator(observer_size, 10)
, m_sock(sock)
, m_our_id(our_id)
@ -169,7 +167,6 @@ rpc_manager::rpc_manager(node_id const& our_id
, m_random_number(generate_random_id())
, m_allocated_observers(0)
, m_destructing(false)
, m_observer(observer)
{
std::srand(time(0));
@ -340,28 +337,6 @@ bool rpc_manager::incoming(msg const& m, node_id* id)
return false;
}
lazy_entry const* ext_ip = ret_ent->dict_find_string("ip");
if (ext_ip && ext_ip->string_length() == 4)
{
// this node claims we use the wrong node-ID!
address_v4::bytes_type b;
memcpy(&b[0], ext_ip->string_ptr(), 4);
if (m_observer)
m_observer->set_external_address(address_v4(b)
, m.addr.address());
}
#if TORRENT_USE_IPV6
else if (ext_ip && ext_ip->string_length() == 16)
{
// this node claims we use the wrong node-ID!
address_v6::bytes_type b;
memcpy(&b[0], ext_ip->string_ptr(), 16);
if (m_observer)
m_observer->set_external_address(address_v6(b)
, m.addr.address());
}
#endif
#ifdef TORRENT_DHT_VERBOSE_LOGGING
TORRENT_LOG(rpc) << "[" << o->m_algorithm.get() << "] Reply with transaction id: "
<< tid << " from " << m.addr;

View File

@ -37,6 +37,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/socket.hpp"
#include "libtorrent/socket_io.hpp"
#include "libtorrent/address.hpp"
#include "libtorrent/io.hpp" // for write_uint16
#include "libtorrent/hasher.hpp" // for hasher
namespace libtorrent
@ -50,18 +51,18 @@ namespace libtorrent
std::string address_to_bytes(address const& a)
{
#if TORRENT_USE_IPV6
if (a.is_v6())
{
address_v6::bytes_type b = a.to_v6().to_bytes();
return std::string((char*)&b[0], b.size());
}
else
#endif
{
address_v4::bytes_type b = a.to_v4().to_bytes();
return std::string((char*)&b[0], b.size());
}
std::string ret;
std::back_insert_iterator<std::string> out(ret);
detail::write_address(a, out);
return ret;
}
std::string endpoint_to_bytes(udp::endpoint const& ep)
{
std::string ret;
std::back_insert_iterator<std::string> out(ret);
detail::write_endpoint(ep, out);
return ret;
}
std::string print_endpoint(tcp::endpoint const& ep)

View File

@ -48,6 +48,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/bloom_filter.hpp"
#include "libtorrent/aux_/session_impl.hpp"
#include "libtorrent/ip_voter.hpp"
#include "libtorrent/socket_io.hpp"
#include <boost/bind.hpp>
#include <iostream>
#include <set>
@ -402,6 +403,14 @@ int test_main()
test1.resize(100, true);
TEST_CHECK(test1.all_set() == true);
// test address_to_bytes
TEST_EQUAL(address_to_bytes(address_v4::from_string("10.11.12.13")), "\x0a\x0b\x0c\x0d");
TEST_EQUAL(address_to_bytes(address_v4::from_string("16.5.127.1")), "\x10\x05\x7f\x01");
// test endpoint_to_bytes
TEST_EQUAL(endpoint_to_bytes(udp::endpoint(address_v4::from_string("10.11.12.13"), 8080)), "\x0a\x0b\x0c\x0d\x1f\x90");
TEST_EQUAL(endpoint_to_bytes(udp::endpoint(address_v4::from_string("16.5.127.1"), 12345)), "\x10\x05\x7f\x01\x30\x39");
return 0;
}