From cc4368b45a411008133115b4f0785154afa32e0d Mon Sep 17 00:00:00 2001 From: arvidn Date: Tue, 18 Aug 2015 18:56:05 +0200 Subject: [PATCH 1/3] attempt to postpone DHT until all outstanding dht router name lookups complete --- include/libtorrent/aux_/session_impl.hpp | 4 ++++ src/session_impl.cpp | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/include/libtorrent/aux_/session_impl.hpp b/include/libtorrent/aux_/session_impl.hpp index a320128a4..0d451d437 100644 --- a/include/libtorrent/aux_/session_impl.hpp +++ b/include/libtorrent/aux_/session_impl.hpp @@ -1009,6 +1009,10 @@ namespace libtorrent // is updated again. This especially matters for // small numbers. int m_dht_interval_update_torrents; + + // the number of DHT router lookups there are currently outstanding. As + // long as this is > 0, we'll postpone starting the DHT + int m_outstanding_router_lookups; #endif bool incoming_packet(error_code const& ec diff --git a/src/session_impl.cpp b/src/session_impl.cpp index fb08b170d..e3f4d7e23 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -416,6 +416,7 @@ namespace aux { #ifndef TORRENT_DISABLE_DHT , m_dht_announce_timer(m_io_service) , m_dht_interval_update_torrents(0) + , m_outstanding_router_lookups(0) #endif , m_external_udp_port(0) , m_udp_socket(m_io_service) @@ -5413,6 +5414,10 @@ retry: INVARIANT_CHECK; stop_dht(); + + // postpone starting the DHT if we're still resolving the DHT router + if (m_outstanding_router_lookups > 0) return; + m_dht = boost::make_shared(static_cast(this) , boost::ref(m_udp_socket), boost::cref(m_dht_settings) , boost::ref(m_stats_counters), &startup_state); @@ -5459,6 +5464,7 @@ retry: #if defined TORRENT_ASIO_DEBUGGING add_outstanding_async("session_impl::on_dht_router_name_lookup"); #endif + ++m_outstanding_router_lookups; m_host_resolver.async_resolve(node.first, resolver_interface::abort_on_shutdown , boost::bind(&session_impl::on_dht_router_name_lookup , this, _1, _2, node.second)); @@ -5470,11 +5476,15 @@ retry: #if defined TORRENT_ASIO_DEBUGGING complete_async("session_impl::on_dht_router_name_lookup"); #endif + --m_outstanding_router_lookups; + if (e) { if (m_alerts.should_post()) m_alerts.emplace_alert( dht_error_alert::hostname_lookup, e); + + if (m_outstanding_router_lookups == 0) update_dht(); return; } @@ -5487,6 +5497,8 @@ retry: if (m_dht) m_dht->add_router_node(ep); m_dht_router_nodes.push_back(ep); } + + if (m_outstanding_router_lookups == 0) update_dht(); } // callback for dht_immutable_get From 347d976a701a4ee94f476a1ba5fdc731f7065593 Mon Sep 17 00:00:00 2001 From: arvidn Date: Tue, 18 Aug 2015 23:35:27 +0200 Subject: [PATCH 2/3] since starting the DHT can be delayed now, also cache dht nodes added while waiting --- include/libtorrent/aux_/session_impl.hpp | 8 ++- include/libtorrent/kademlia/dht_tracker.hpp | 5 -- src/kademlia/dht_tracker.cpp | 16 ------ src/session_impl.cpp | 55 ++++++++++++++++++--- 4 files changed, 54 insertions(+), 30 deletions(-) diff --git a/include/libtorrent/aux_/session_impl.hpp b/include/libtorrent/aux_/session_impl.hpp index 0d451d437..d7fe70e48 100644 --- a/include/libtorrent/aux_/session_impl.hpp +++ b/include/libtorrent/aux_/session_impl.hpp @@ -328,6 +328,8 @@ namespace libtorrent entry dht_state() const; #endif void on_dht_announce(error_code const& e); + void on_dht_name_lookup(error_code const& e + , std::vector
const& addresses, int port); void on_dht_router_name_lookup(error_code const& e , std::vector
const& addresses, int port); #endif @@ -996,7 +998,11 @@ namespace libtorrent // these are used when starting the DHT // (and bootstrapping it), and then erased - std::list m_dht_router_nodes; + std::vector m_dht_router_nodes; + + // if a DHT node is added when there's no DHT instance, they're stored + // here until we start the DHT + std::vector m_dht_nodes; // this announce timer is used // by the DHT. diff --git a/include/libtorrent/kademlia/dht_tracker.hpp b/include/libtorrent/kademlia/dht_tracker.hpp index 1f46a361e..3608d9c4a 100644 --- a/include/libtorrent/kademlia/dht_tracker.hpp +++ b/include/libtorrent/kademlia/dht_tracker.hpp @@ -80,7 +80,6 @@ namespace libtorrent { namespace dht void stop(); void add_node(udp::endpoint node); - void add_node(std::pair const& node); void add_router_node(udp::endpoint const& node); entry state() const; @@ -126,10 +125,6 @@ namespace libtorrent { namespace dht boost::shared_ptr self() { return shared_from_this(); } - void on_name_lookup(error_code const& e - , udp::resolver::iterator host); - void on_router_name_lookup(error_code const& e - , udp::resolver::iterator host); void connection_timeout(error_code const& e); void refresh_timeout(error_code const& e); void tick(error_code const& e); diff --git a/src/kademlia/dht_tracker.cpp b/src/kademlia/dht_tracker.cpp index 549856114..06b057b02 100644 --- a/src/kademlia/dht_tracker.cpp +++ b/src/kademlia/dht_tracker.cpp @@ -442,22 +442,6 @@ namespace libtorrent { namespace dht m_dht.add_node(node); } - void dht_tracker::add_node(std::pair const& node) - { - char port[7]; - snprintf(port, sizeof(port), "%d", node.second); - udp::resolver::query q(node.first, port); - m_host_resolver.async_resolve(q, - boost::bind(&dht_tracker::on_name_lookup, self(), _1, _2)); - } - - void dht_tracker::on_name_lookup(error_code const& e - , udp::resolver::iterator host) - { - if (e || host == udp::resolver::iterator()) return; - add_node(host->endpoint()); - } - void dht_tracker::add_router_node(udp::endpoint const& node) { m_dht.add_router_node(node); diff --git a/src/session_impl.cpp b/src/session_impl.cpp index e3f4d7e23..c0399dc1f 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -3354,6 +3354,7 @@ retry: TORRENT_ASSERT(is_single_thread()); if (m_dht) m_dht->add_node(n); + else m_dht_nodes.push_back(n); } bool session_impl::has_dht() const @@ -4510,11 +4511,13 @@ retry: #ifndef TORRENT_DISABLE_DHT // add p.dht_nodes to the DHT, if enabled - if (m_dht && !p.dht_nodes.empty()) + if (!p.dht_nodes.empty()) { for (std::vector >::const_iterator i = p.dht_nodes.begin() , end(p.dht_nodes.end()); i != end; ++i) - m_dht->add_node(*i); + { + add_dht_node_name(*i); + } } #endif @@ -4669,10 +4672,11 @@ retry: if (m_dht && params.ti) { torrent_info::nodes_t const& nodes = params.ti->nodes(); - std::for_each(nodes.begin(), nodes.end(), boost::bind( - static_cast const&)>( - &dht::dht_tracker::add_node) - , boost::ref(m_dht), _1)); + for (std::vector >::const_iterator i = nodes.begin() + , end(nodes.end()); i != end; ++i) + { + add_dht_node_name(*i); + } } #endif @@ -5422,12 +5426,19 @@ retry: , boost::ref(m_udp_socket), boost::cref(m_dht_settings) , boost::ref(m_stats_counters), &startup_state); - for (std::list::iterator i = m_dht_router_nodes.begin() + for (std::vector::iterator i = m_dht_router_nodes.begin() , end(m_dht_router_nodes.end()); i != end; ++i) { m_dht->add_router_node(*i); } + for (std::vector::iterator i = m_dht_nodes.begin() + , end(m_dht_nodes.end()); i != end; ++i) + { + m_dht->add_node(*i); + } + m_dht_nodes.clear(); + m_dht->start(startup_state, boost::bind(&on_bootstrap, boost::ref(m_alerts))); m_udp_socket.subscribe(m_dht.get()); @@ -5456,7 +5467,35 @@ retry: void session_impl::add_dht_node_name(std::pair const& node) { - if (m_dht) m_dht->add_node(node); +#if defined TORRENT_ASIO_DEBUGGING + add_outstanding_async("session_impl::on_dht_name_lookup"); +#endif + m_host_resolver.async_resolve(node.first, resolver_interface::abort_on_shutdown + , boost::bind(&session_impl::on_dht_name_lookup + , this, _1, _2, node.second)); + } + + void session_impl::on_dht_name_lookup(error_code const& e + , std::vector
const& addresses, int port) + { +#if defined TORRENT_ASIO_DEBUGGING + complete_async("session_impl::on_dht_name_lookup"); +#endif + + if (e) + { + if (m_alerts.should_post()) + m_alerts.emplace_alert( + dht_error_alert::hostname_lookup, e); + return; + } + + for (std::vector
::const_iterator i = addresses.begin() + , end(addresses.end()); i != end; ++i) + { + udp::endpoint ep(*i, port); + add_dht_node(ep); + } } void session_impl::add_dht_router(std::pair const& node) From 8bc4bf1e1a8578efa7c7ff38dde1729ab25a8fd8 Mon Sep 17 00:00:00 2001 From: arvidn Date: Wed, 19 Aug 2015 01:43:44 +0200 Subject: [PATCH 3/3] remove incorrect check for m_dht --- src/session_impl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/session_impl.cpp b/src/session_impl.cpp index c0399dc1f..a20e7be5f 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -4669,7 +4669,7 @@ retry: #endif #ifndef TORRENT_DISABLE_DHT - if (m_dht && params.ti) + if (params.ti) { torrent_info::nodes_t const& nodes = params.ti->nodes(); for (std::vector >::const_iterator i = nodes.begin()