merged DHT change from RC_0_16
This commit is contained in:
parent
b7ae64fd1f
commit
50f051433a
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
std::string ret;
|
||||
std::back_insert_iterator<std::string> out(ret);
|
||||
detail::write_address(a, out);
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
std::string endpoint_to_bytes(udp::endpoint const& ep)
|
||||
{
|
||||
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_endpoint(ep, out);
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string print_endpoint(tcp::endpoint const& ep)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue