don't leak exceptions out of handler callbacks in resolver

This commit is contained in:
Arvid Norberg 2019-05-13 22:46:17 -07:00 committed by Arvid Norberg
parent 41a5940100
commit 16acd9ebe1
2 changed files with 24 additions and 8 deletions

View File

@ -62,7 +62,10 @@ struct TORRENT_EXTRA_EXPORT resolver final : resolver_interface
private: private:
void on_lookup(error_code const& ec, tcp::resolver::iterator i void on_lookup(error_code const& ec, tcp::resolver::iterator i
, resolver_interface::callback_t h, std::string hostname); , resolver_interface::callback_t const& h, std::string const& hostname);
void callback(resolver_interface::callback_t const& h
, error_code const& ec, std::vector<address> const& ips);
struct dns_cache_entry struct dns_cache_entry
{ {

View File

@ -48,13 +48,24 @@ namespace libtorrent {
, m_timeout(seconds(1200)) , m_timeout(seconds(1200))
{} {}
void resolver::callback(resolver_interface::callback_t const& h
, error_code const& ec, std::vector<address> const& ips)
{
try {
h(ec, ips);
} catch (std::exception&) {
TORRENT_ASSERT_FAIL();
}
}
void resolver::on_lookup(error_code const& ec, tcp::resolver::iterator i void resolver::on_lookup(error_code const& ec, tcp::resolver::iterator i
, resolver_interface::callback_t h, std::string hostname) , resolver_interface::callback_t const& h, std::string const& hostname)
{ {
COMPLETE_ASYNC("resolver::on_lookup"); COMPLETE_ASYNC("resolver::on_lookup");
if (ec) if (ec)
{ {
h(ec, {}); callback(h, ec, {});
return; return;
} }
@ -67,7 +78,7 @@ namespace libtorrent {
++i; ++i;
} }
h(ec, ce.addresses); callback(h, ec, ce.addresses);
// if m_cache grows too big, weed out the // if m_cache grows too big, weed out the
// oldest entries // oldest entries
@ -94,7 +105,7 @@ namespace libtorrent {
address const ip = make_address(host, ec); address const ip = make_address(host, ec);
if (!ec) if (!ec)
{ {
m_ios.post(std::bind(h, ec, std::vector<address>{ip})); m_ios.post([=]{ callback(h, ec, std::vector<address>{ip}); });
return; return;
} }
ec.clear(); ec.clear();
@ -106,7 +117,8 @@ namespace libtorrent {
if ((flags & resolver_interface::cache_only) if ((flags & resolver_interface::cache_only)
|| i->second.last_seen + m_timeout >= aux::time_now()) || i->second.last_seen + m_timeout >= aux::time_now())
{ {
m_ios.post(std::bind(h, ec, i->second.addresses)); std::vector<address> ips = i->second.addresses;
m_ios.post([=] { callback(h, ec, ips); });
return; return;
} }
} }
@ -114,8 +126,9 @@ namespace libtorrent {
if (flags & resolver_interface::cache_only) if (flags & resolver_interface::cache_only)
{ {
// we did not find a cache entry, fail the lookup // we did not find a cache entry, fail the lookup
m_ios.post(std::bind(h, boost::asio::error::host_not_found m_ios.post([=] {
, std::vector<address>{})); callback(h, boost::asio::error::host_not_found, std::vector<address>{});
});
return; return;
} }