forked from premiere/premiere-libtorrent
avoid executing timed async task if the dht node is already removed (#2133)
This commit is contained in:
parent
de90419712
commit
80036f0377
|
@ -162,7 +162,7 @@ namespace libtorrent { namespace dht {
|
|||
std::shared_ptr<dht_tracker> self()
|
||||
{ return shared_from_this(); }
|
||||
|
||||
void connection_timeout(tracker_node& n, error_code const& e);
|
||||
void connection_timeout(aux::session_listen_socket* s, error_code const& e);
|
||||
void refresh_timeout(error_code const& e);
|
||||
void refresh_key(error_code const& e);
|
||||
void update_storage_node_ids();
|
||||
|
|
|
@ -227,3 +227,50 @@ TORRENT_TEST(dht_rate_limit)
|
|||
|
||||
#endif // #if !defined TORRENT_DISABLE_EXTENSIONS && !defined TORRENT_DISABLE_DHT
|
||||
}
|
||||
|
||||
// TODO: put test here to take advantage of existing code, refactor
|
||||
TORRENT_TEST(dht_delete_socket)
|
||||
{
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
|
||||
sim::default_config cfg;
|
||||
sim::simulation sim(cfg);
|
||||
sim::asio::io_service dht_ios(sim, lt::address_v4::from_string("40.30.20.10"));
|
||||
|
||||
lt::udp_socket sock(dht_ios);
|
||||
error_code ec;
|
||||
sock.bind(udp::endpoint(address_v4::from_string("40.30.20.10"), 8888), ec);
|
||||
|
||||
obs o;
|
||||
mock_socket ds;
|
||||
dht_settings dhtsett;
|
||||
counters cnt;
|
||||
dht::dht_state state;
|
||||
std::unique_ptr<lt::dht::dht_storage_interface> dht_storage(dht::dht_default_storage_constructor(dhtsett));
|
||||
auto dht = std::make_shared<lt::dht::dht_tracker>(
|
||||
&o, dht_ios, std::bind(&send_packet, std::ref(sock), _1, _2, _3, _4, _5)
|
||||
, dhtsett, cnt, *dht_storage, state);
|
||||
|
||||
dht->start([](std::vector<std::pair<dht::node_entry, std::string>> const&){});
|
||||
dht->new_socket(&ds);
|
||||
|
||||
// schedule the removal of the socket at exactly 2 second,
|
||||
// this simulates the fact that the internal scheduled call
|
||||
// to connection_timeout will be executed right after leaving
|
||||
// the state of cancellable
|
||||
asio::high_resolution_timer t1(dht_ios);
|
||||
t1.expires_from_now(chrono::seconds(2));
|
||||
t1.async_wait([&](error_code const&)
|
||||
{
|
||||
dht->delete_socket(&ds);
|
||||
});
|
||||
|
||||
// stop the DHT
|
||||
asio::high_resolution_timer t2(dht_ios);
|
||||
t2.expires_from_now(chrono::seconds(3));
|
||||
t2.async_wait([&](error_code const&) { dht->stop(); });
|
||||
|
||||
sim.run();
|
||||
|
||||
#endif // TORRENT_DISABLE_DHT
|
||||
}
|
||||
|
|
|
@ -149,8 +149,8 @@ namespace libtorrent { namespace dht {
|
|||
error_code ec;
|
||||
n.first->second.connection_timer.expires_from_now(seconds(1), ec);
|
||||
n.first->second.connection_timer.async_wait(
|
||||
std::bind(&dht_tracker::connection_timeout, self(), std::ref(n.first->second), _1));
|
||||
n.first->second.dht.bootstrap(std::vector<udp::endpoint>(), find_data::nodes_callback());
|
||||
std::bind(&dht_tracker::connection_timeout, self(), n.first->first, _1));
|
||||
n.first->second.dht.bootstrap({}, find_data::nodes_callback());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,7 +176,7 @@ namespace libtorrent { namespace dht {
|
|||
{
|
||||
n.second.connection_timer.expires_from_now(seconds(1), ec);
|
||||
n.second.connection_timer.async_wait(
|
||||
std::bind(&dht_tracker::connection_timeout, self(), std::ref(n.second), _1));
|
||||
std::bind(&dht_tracker::connection_timeout, self(), n.first, _1));
|
||||
#if TORRENT_USE_IPV6
|
||||
if (n.first->get_local_endpoint().protocol() == tcp::v6())
|
||||
n.second.dht.bootstrap(concat(m_state.nodes6, m_state.nodes), f);
|
||||
|
@ -242,15 +242,21 @@ namespace libtorrent { namespace dht {
|
|||
add_dht_counters(n.second.dht, c);
|
||||
}
|
||||
|
||||
void dht_tracker::connection_timeout(tracker_node& n, error_code const& e)
|
||||
void dht_tracker::connection_timeout(aux::session_listen_socket* s, error_code const& e)
|
||||
{
|
||||
if (e || !m_running) return;
|
||||
|
||||
time_duration d = n.dht.connection_timeout();
|
||||
auto const it = m_nodes.find(s);
|
||||
// this could happen if the task is about to be executed (and not cancellable) and
|
||||
// the socket is just removed
|
||||
if (it == m_nodes.end()) return; // node already destroyed
|
||||
|
||||
tracker_node& n = it->second;
|
||||
time_duration const d = n.dht.connection_timeout();
|
||||
error_code ec;
|
||||
deadline_timer& timer = n.connection_timer;
|
||||
timer.expires_from_now(d, ec);
|
||||
timer.async_wait(std::bind(&dht_tracker::connection_timeout, self(), std::ref(n), _1));
|
||||
timer.async_wait(std::bind(&dht_tracker::connection_timeout, self(), s, _1));
|
||||
}
|
||||
|
||||
void dht_tracker::refresh_timeout(error_code const& e)
|
||||
|
@ -644,6 +650,8 @@ namespace libtorrent { namespace dht {
|
|||
|
||||
bool dht_tracker::send_packet(aux::session_listen_socket* s, entry& e, udp::endpoint const& addr)
|
||||
{
|
||||
TORRENT_ASSERT(m_nodes.find(s) != m_nodes.end());
|
||||
|
||||
static char const version_str[] = {'L', 'T'
|
||||
, LIBTORRENT_VERSION_MAJOR, LIBTORRENT_VERSION_MINOR};
|
||||
e["v"] = std::string(version_str, version_str + 4);
|
||||
|
|
Loading…
Reference in New Issue