diff --git a/include/libtorrent/aux_/session_impl.hpp b/include/libtorrent/aux_/session_impl.hpp index 87bc7d4ad..d1e4b72a8 100644 --- a/include/libtorrent/aux_/session_impl.hpp +++ b/include/libtorrent/aux_/session_impl.hpp @@ -569,15 +569,16 @@ namespace libtorrent // implements dht_observer virtual void set_external_address(address const& ip - , address const& source); - virtual void get_peers(sha1_hash const& ih); - virtual void announce(sha1_hash const& ih, address const& addr, int port); + , address const& source) TORRENT_OVERRIDE; + virtual address external_address() TORRENT_OVERRIDE; + virtual void get_peers(sha1_hash const& ih) TORRENT_OVERRIDE; + virtual void announce(sha1_hash const& ih, address const& addr, int port) TORRENT_OVERRIDE; virtual void outgoing_get_peers(sha1_hash const& target - , sha1_hash const& sent_target, udp::endpoint const& ep); + , sha1_hash const& sent_target, udp::endpoint const& ep) TORRENT_OVERRIDE; void set_external_address(address const& ip , int source_type, address const& source); - virtual external_ip const& external_address() const; + virtual external_ip const& external_address() const TORRENT_OVERRIDE; // used when posting synchronous function // calls to session_impl and torrent objects diff --git a/include/libtorrent/kademlia/dht_observer.hpp b/include/libtorrent/kademlia/dht_observer.hpp index f5dc6437e..953859a5c 100644 --- a/include/libtorrent/kademlia/dht_observer.hpp +++ b/include/libtorrent/kademlia/dht_observer.hpp @@ -42,6 +42,7 @@ namespace libtorrent { namespace dht { virtual void set_external_address(address const& addr , address const& source) = 0; + virtual address external_address() = 0; virtual void get_peers(sha1_hash const& ih) = 0; virtual void outgoing_get_peers(sha1_hash const& target , sha1_hash const& sent_target, udp::endpoint const& ep) = 0; diff --git a/include/libtorrent/kademlia/dht_tracker.hpp b/include/libtorrent/kademlia/dht_tracker.hpp index d63a0a951..3d76eccb9 100644 --- a/include/libtorrent/kademlia/dht_tracker.hpp +++ b/include/libtorrent/kademlia/dht_tracker.hpp @@ -76,7 +76,7 @@ namespace libtorrent { namespace dht , udp_socket_observer , boost::enable_shared_from_this { - dht_tracker(libtorrent::aux::session_impl& ses, rate_limited_udp_socket& sock + dht_tracker(dht_observer* observer, rate_limited_udp_socket& sock , dht_settings const& settings, counters& cnt, entry const* state = 0); virtual ~dht_tracker(); diff --git a/include/libtorrent/kademlia/node.hpp b/include/libtorrent/kademlia/node.hpp index 9b20b36c2..32729651e 100644 --- a/include/libtorrent/kademlia/node.hpp +++ b/include/libtorrent/kademlia/node.hpp @@ -206,7 +206,7 @@ typedef std::map dht_mutable_table_t; public: node_impl(udp_socket_interface* sock - , libtorrent::dht_settings const& settings, node_id nid, address const& external_address + , libtorrent::dht_settings const& settings, node_id nid , dht_observer* observer, counters& cnt); virtual ~node_impl() {} diff --git a/src/kademlia/dht_tracker.cpp b/src/kademlia/dht_tracker.cpp index e6ee45e7a..3d3fdc45c 100644 --- a/src/kademlia/dht_tracker.cpp +++ b/src/kademlia/dht_tracker.cpp @@ -41,13 +41,12 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/kademlia/dht_tracker.hpp" #include "libtorrent/kademlia/msg.hpp" -// TODO: it would be nice to not have a dependency on session here -#include "libtorrent/aux_/session_impl.hpp" #include "libtorrent/socket.hpp" #include "libtorrent/socket_io.hpp" #include "libtorrent/bencode.hpp" #include "libtorrent/io.hpp" #include "libtorrent/version.hpp" +#include "libtorrent/time.hpp" #include "libtorrent/performance_counters.hpp" // for counters using boost::ref; @@ -139,16 +138,15 @@ namespace libtorrent { namespace dht // class that puts the networking and the kademlia node in a single // unit and connecting them together. - // TODO: 3 don't pass in session here. pass in dht_observer and maybe add - // a way to ask it for the external IP. use bdecode_node instead of entry - dht_tracker::dht_tracker(libtorrent::aux::session_impl& ses + dht_tracker::dht_tracker(dht_observer* observer , rate_limited_udp_socket& sock - , dht_settings const& settings, counters& cnt, entry const* state) + , dht_settings const& settings + , counters& cnt + , entry const* state) : m_counters(cnt) - , m_dht(this, settings, extract_node_id(state) - , ses.external_address().external_address(address_v4()), &ses, cnt) + , m_dht(this, settings, extract_node_id(state), observer, cnt) , m_sock(sock) - , m_last_new_key(aux::time_now() - minutes(int(key_refresh))) + , m_last_new_key(clock_type::now() - minutes(int(key_refresh))) , m_timer(sock.get_io_service()) , m_connection_timer(sock.get_io_service()) , m_refresh_timer(sock.get_io_service()) @@ -257,7 +255,7 @@ namespace libtorrent { namespace dht m_timer.expires_from_now(minutes(tick_period), ec); m_timer.async_wait(boost::bind(&dht_tracker::tick, self(), _1)); - time_point now = aux::time_now(); + time_point now = clock_type::now(); if (now - minutes(int(key_refresh)) > m_last_new_key) { m_last_new_key = now; @@ -399,7 +397,7 @@ namespace libtorrent { namespace dht return true; } - if (!m_blocker.incoming(ep.address(), aux::time_now())) + if (!m_blocker.incoming(ep.address(), clock_type::now())) return true; using libtorrent::entry; diff --git a/src/kademlia/node.cpp b/src/kademlia/node.cpp index 24801ce49..e902d257e 100644 --- a/src/kademlia/node.cpp +++ b/src/kademlia/node.cpp @@ -96,14 +96,24 @@ void purge_peers(std::set& peers) void nop() {} +node_id calculate_node_id(node_id const& nid, dht_observer* observer) +{ + address external_address; + if (observer) external_address = observer->external_address(); + if (nid == (node_id::min)() || !verify_id(nid, external_address)) + return generate_id(external_address); + + return nid; +} + } // anonymous namespace node_impl::node_impl(udp_socket_interface* sock - , dht_settings const& settings, node_id nid, address const& external_address + , dht_settings const& settings, node_id nid , dht_observer* observer , struct counters& cnt) : m_settings(settings) - , m_id(nid == (node_id::min)() || !verify_id(nid, external_address) ? generate_id(external_address) : nid) + , m_id(calculate_node_id(nid, observer)) , m_table(m_id, 8, settings) , m_rpc(m_id, m_table, sock) , m_observer(observer) diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 77b2391ce..11671e1c4 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -818,6 +818,9 @@ namespace aux { settings = e->dict_find_dict("dht state"); if (settings) { + // TODO: 2 if the DHT is enabled, it should probably be restarted here. + // maybe it should even be deferred to not be started until the client + // has had a chance to pass in the dht state m_dht_state = settings; } #endif @@ -5391,13 +5394,12 @@ retry: } } - // TODO: 3 use bdecode_node instead of entry. void session_impl::start_dht(entry const& startup_state) { INVARIANT_CHECK; stop_dht(); - m_dht = boost::make_shared(boost::ref(*this) + m_dht = boost::make_shared((dht_observer*)this , boost::ref(m_udp_socket), boost::cref(m_dht_settings) , boost::ref(m_stats_counters), &startup_state); @@ -6429,31 +6431,38 @@ retry: m_upnp.reset(); } - external_ip const& session_impl::external_address() const - { return m_external_ip; } + external_ip const& session_impl::external_address() const TORRENT_OVERRIDE + { + return m_external_ip; + } // this is the DHT observer version. DHT is the implied source void session_impl::set_external_address(address const& ip - , address const& source) + , address const& source) TORRENT_OVERRIDE { set_external_address(ip, source_dht, source); } - void session_impl::get_peers(sha1_hash const& ih) + address session_impl::external_address() TORRENT_OVERRIDE + { + return m_external_ip.external_address(address_v4()); + } + + void session_impl::get_peers(sha1_hash const& ih) TORRENT_OVERRIDE { if (!m_alerts.should_post()) return; m_alerts.emplace_alert(ih); } void session_impl::announce(sha1_hash const& ih, address const& addr - , int port) + , int port) TORRENT_OVERRIDE { if (!m_alerts.should_post()) return; m_alerts.emplace_alert(addr, port, ih); } void session_impl::outgoing_get_peers(sha1_hash const& target - , sha1_hash const& sent_target, udp::endpoint const& ep) + , sha1_hash const& sent_target, udp::endpoint const& ep) TORRENT_OVERRIDE { if (!m_alerts.should_post()) return; m_alerts.emplace_alert(target, sent_target, ep); diff --git a/test/test_dht.cpp b/test/test_dht.cpp index a1b14a0b9..f98651985 100644 --- a/test/test_dht.cpp +++ b/test/test_dht.cpp @@ -45,6 +45,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/kademlia/node_id.hpp" #include "libtorrent/kademlia/routing_table.hpp" #include "libtorrent/kademlia/item.hpp" +#include "libtorrent/kademlia/dht_observer.hpp" #include "libtorrent/ed25519.hpp" #include @@ -418,6 +419,22 @@ bool get_item_cb(dht::item& i) return false; } +struct obs : dht::dht_observer +{ + virtual void set_external_address(address const& addr + , address const& source) TORRENT_OVERRIDE + {} + + virtual address external_address() TORRENT_OVERRIDE + { + return address_v4::from_string("236.0.0.1"); + } + virtual void get_peers(sha1_hash const& ih) TORRENT_OVERRIDE {} + virtual void outgoing_get_peers(sha1_hash const& target + , sha1_hash const& sent_target, udp::endpoint const& ep) TORRENT_OVERRIDE {} + virtual void announce(sha1_hash const& ih, address const& addr, int port) TORRENT_OVERRIDE {} +}; + // TODO: test obfuscated_get_peers int test_main() { @@ -425,10 +442,10 @@ int test_main() sett.max_torrents = 4; sett.max_dht_items = 4; sett.enforce_node_id = false; - address ext = address::from_string("236.0.0.1"); mock_socket s; + obs observer; counters cnt; - dht::node_impl node(&s, sett, node_id(0), ext, 0, cnt); + dht::node_impl node(&s, sett, node_id(0), &observer, cnt); // DHT should be running on port 48199 now bdecode_node response; @@ -1445,7 +1462,7 @@ int test_main() g_sent_packets.clear(); do { - dht::node_impl node(&s, sett, node_id::min(), ext, 0, cnt); + dht::node_impl node(&s, sett, (node_id::min)(), &observer, cnt); udp::endpoint initial_node(address_v4::from_string("4.4.4.4"), 1234); std::vector nodesv; @@ -1517,7 +1534,7 @@ int test_main() do { dht::node_id target = to_hash("1234876923549721020394873245098347598635"); - dht::node_impl node(&s, sett, node_id::min(), ext, 0, cnt); + dht::node_impl node(&s, sett, (node_id::min)(), &observer, cnt); udp::endpoint initial_node(address_v4::from_string("4.4.4.4"), 1234); node.m_table.add_node(initial_node); @@ -1610,7 +1627,7 @@ int test_main() g_sent_packets.clear(); do { - dht::node_impl node(&s, sett, node_id::min(), ext, 0, cnt); + dht::node_impl node(&s, sett, (node_id::min)(), &observer, cnt); udp::endpoint initial_node(address_v4::from_string("4.4.4.4"), 1234); node.m_table.add_node(initial_node); @@ -1656,7 +1673,7 @@ int test_main() g_sent_packets.clear(); do { - dht::node_impl node(&s, sett, node_id::min(), ext, 0, cnt); + dht::node_impl node(&s, sett, (node_id::min)(), &observer, cnt); udp::endpoint initial_node(address_v4::from_string("4.4.4.4"), 1234); node.m_table.add_node(initial_node); @@ -1732,7 +1749,7 @@ int test_main() g_sent_packets.clear(); do { - dht::node_impl node(&s, sett, node_id::min(), ext, 0, cnt); + dht::node_impl node(&s, sett, (node_id::min)(), &observer, cnt); enum { num_test_nodes = 2 }; node_entry nodes[num_test_nodes] = { node_entry(generate_next(), udp::endpoint(address_v4::from_string("4.4.4.4"), 1234)) @@ -1814,7 +1831,7 @@ int test_main() g_sent_packets.clear(); do { - dht::node_impl node(&s, sett, node_id::min(), ext, 0, cnt); + dht::node_impl node(&s, sett, (node_id::min)(), &observer, cnt); enum { num_test_nodes = 2 }; node_entry nodes[num_test_nodes] = { node_entry(generate_next(), udp::endpoint(address_v4::from_string("4.4.4.4"), 1234))