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
This commit is contained in:
Arvid Norberg 2017-05-25 14:58:29 -04:00 committed by GitHub
parent 432131e493
commit 94701c24da
5 changed files with 33 additions and 24 deletions

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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<address>()));
return;
}
// the port is ignored
tcp::resolver::query q(host, "80");

View File

@ -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));