From 94701c24da1f1071afc98c70d27ea5c75d6ac56f Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Thu, 25 May 2017 14:58:29 -0400 Subject: [PATCH] when stopping a torrent, never perform a name lookup on the tracker (#2021) when stopping a torrent, never perform a name lookup on the tracker, only announce to trackers whose IP we already know. This is expected to make shutdowns not hang --- ChangeLog | 1 + include/libtorrent/resolver_interface.hpp | 9 +++--- src/http_tracker_connection.cpp | 4 +-- src/resolver.cpp | 36 ++++++++++++++--------- src/udp_tracker_connection.cpp | 7 ++--- 5 files changed, 33 insertions(+), 24 deletions(-) diff --git a/ChangeLog b/ChangeLog index e975c7308..13311c0f1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ + * improve shutdown time by only announcing to trackers whose IP we know * fix python3 portability issue in python binding * delay 5 seconds before reconnecting socks5 proxy for UDP ASSOCIATE * fix NAT-PMP crash when removing a mapping at the wrong time diff --git a/include/libtorrent/resolver_interface.hpp b/include/libtorrent/resolver_interface.hpp index b410465c6..95fedde3b 100644 --- a/include/libtorrent/resolver_interface.hpp +++ b/include/libtorrent/resolver_interface.hpp @@ -53,10 +53,11 @@ struct TORRENT_EXTRA_EXPORT resolver_interface enum flags_t { - // this flag will make async_resolve() always use the cache if we have an - // entry, regardless of how old it is. This is usefull when completing the - // lookup quickly is more important than accuracy - prefer_cache = 1, + // this flag will make async_resolve() only use the cache and fail if we + // don't have a cache entry, regardless of how old it is. This is usefull + // when completing the lookup quickly is more important than accuracy, + // like on shutdown + cache_only = 1, // set this flag for lookups that are not critical during shutdown. i.e. // for looking up tracker names _except_ when stopping a tracker. diff --git a/src/http_tracker_connection.cpp b/src/http_tracker_connection.cpp index 472c1714c..ad39f1e60 100644 --- a/src/http_tracker_connection.cpp +++ b/src/http_tracker_connection.cpp @@ -229,8 +229,8 @@ namespace libtorrent , ps.proxy_tracker_connections ? &ps : NULL , 5, user_agent, bind_interface() , tracker_req().event == tracker_request::stopped - ? resolver_interface::prefer_cache - : resolver_interface::abort_on_shutdown + ? resolver_interface::cache_only : 0 + | resolver_interface::abort_on_shutdown #ifndef TORRENT_NO_DEPRECATE , tracker_req().auth #else diff --git a/src/resolver.cpp b/src/resolver.cpp index a493386eb..4a444ace9 100644 --- a/src/resolver.cpp +++ b/src/resolver.cpp @@ -87,22 +87,9 @@ namespace libtorrent } } - void resolver::async_resolve(std::string const& host, int flags + void resolver::async_resolve(std::string const& host, int const flags , resolver_interface::callback_t const& h) { - cache_t::iterator i = m_cache.find(host); - if (i != m_cache.end()) - { - // keep cache entries valid for m_timeout seconds - if ((flags & resolver_interface::prefer_cache) - || i->second.last_seen + m_timeout >= aux::time_now()) - { - error_code ec; - m_ios.post(boost::bind(h, ec, i->second.addresses)); - return; - } - } - // special handling for raw IP addresses. There's no need to get in line // behind actual lookups if we can just resolve it immediately. error_code ec; @@ -114,6 +101,27 @@ namespace libtorrent m_ios.post(boost::bind(h, ec, addresses)); return; } + ec.clear(); + + cache_t::iterator i = m_cache.find(host); + if (i != m_cache.end()) + { + // keep cache entries valid for m_timeout seconds + if ((flags & resolver_interface::cache_only) + || i->second.last_seen + m_timeout >= aux::time_now()) + { + m_ios.post(boost::bind(h, ec, i->second.addresses)); + return; + } + } + + if (flags & resolver_interface::cache_only) + { + // we did not find a cache entry, fail the lookup + m_ios.post(boost::bind(h, boost::asio::error::host_not_found + , std::vector
())); + return; + } // the port is ignored tcp::resolver::query q(host, "80"); diff --git a/src/udp_tracker_connection.cpp b/src/udp_tracker_connection.cpp index 141f81b34..785ebcbc1 100644 --- a/src/udp_tracker_connection.cpp +++ b/src/udp_tracker_connection.cpp @@ -112,13 +112,12 @@ namespace libtorrent #if defined TORRENT_ASIO_DEBUGGING add_outstanding_async("udp_tracker_connection::name_lookup"); #endif - // when stopping, pass in the prefer cache flag, because we + // when stopping, pass in the cache-only flag, because we // don't want to get stuck on DNS lookups when shutting down - // if we can avoid it m_man.host_resolver().async_resolve(hostname , tracker_req().event == tracker_request::stopped - ? resolver_interface::prefer_cache - : resolver_interface::abort_on_shutdown + ? resolver_interface::cache_only : 0 + | resolver_interface::abort_on_shutdown , boost::bind(&udp_tracker_connection::name_lookup , shared_from_this(), _1, _2, port));