enable/disable the internal ip notifier with new setting (#2487)

This commit is contained in:
Alden Torres 2017-11-01 05:51:51 -04:00 committed by Arvid Norberg
parent f02e7514e1
commit 5480c08184
6 changed files with 94 additions and 9 deletions

View File

@ -614,10 +614,12 @@ namespace aux {
, error_code const& e); , error_code const& e);
#endif #endif
void start_ip_notifier();
void start_lsd(); void start_lsd();
natpmp* start_natpmp(); natpmp* start_natpmp();
upnp* start_upnp(); upnp* start_upnp();
void stop_ip_notifier();
void stop_lsd(); void stop_lsd();
void stop_natpmp(); void stop_natpmp();
void stop_upnp(); void stop_upnp();
@ -715,6 +717,7 @@ namespace aux {
void update_max_failcount(); void update_max_failcount();
void update_resolver_cache_timeout(); void update_resolver_cache_timeout();
void update_ip_notifier();
void update_upnp(); void update_upnp();
void update_natpmp(); void update_natpmp();
void update_lsd(); void update_lsd();

View File

@ -716,6 +716,16 @@ namespace libtorrent {
// any. // any.
proxy_tracker_connections, proxy_tracker_connections,
// Starts and stops the internal IP table route changes notifier.
//
// The current implementation supports multiple platforms, and it is
// recommended to have it enable, but you may want to disable it if
// it's supported but unreliable, or if you have a better way to
// detect the changes. In the later case, you should manually call
// ``session_handle::reopen_network_sockets`` to ensure network
// changes are taken in consideration.
enable_ip_notifier,
max_bool_setting_internal max_bool_setting_internal
}; };

View File

@ -64,3 +64,51 @@ TORRENT_TEST(seed_mode)
}); });
} }
TORRENT_TEST(ip_notifier_setting)
{
int s_tick = 0;
int working_count = 0;
setup_swarm(1, swarm_test::upload
// add session
, [](lt::settings_pack& pack)
{
pack.set_int(settings_pack::tick_interval, 1000);
pack.set_int(settings_pack::alert_mask, alert::all_categories);
}
// add torrent
, [](lt::add_torrent_params& params) {}
// on alert
, [&s_tick, &working_count](lt::alert const* a, lt::session& ses)
{
std::string const msg = a->message();
if (msg.find("received error on_ip_change:") != std::string::npos)
{
TEST_CHECK(s_tick == 0 || s_tick == 2);
working_count++;
}
}
// terminate
, [&s_tick](int ticks, lt::session& ses) -> bool {
if (ticks == 1)
{
settings_pack sp;
sp.set_bool(settings_pack::enable_ip_notifier, false);
ses.apply_settings(sp);
}
else if (ticks == 2)
{
settings_pack sp;
sp.set_bool(settings_pack::enable_ip_notifier, true);
ses.apply_settings(sp);
}
s_tick = ticks;
// exit after 3 seconds
return ticks > 3;
});
TEST_EQUAL(working_count, 2);
}

View File

@ -91,7 +91,7 @@ struct ip_change_notifier_impl final : ip_change_notifier
{ {
using namespace std::placeholders; using namespace std::placeholders;
m_socket.async_receive(boost::asio::buffer(m_buf) m_socket.async_receive(boost::asio::buffer(m_buf)
, std::bind(&ip_change_notifier_impl::on_notify, this, _1, _2, std::move(cb))); , std::bind(&ip_change_notifier_impl::on_notify, _1, _2, std::move(cb)));
} }
void cancel() override void cancel() override
@ -101,7 +101,7 @@ private:
netlink::socket m_socket; netlink::socket m_socket;
std::array<char, 4096> m_buf; std::array<char, 4096> m_buf;
void on_notify(error_code const& ec, std::size_t bytes_transferred static void on_notify(error_code const& ec, std::size_t bytes_transferred
, std::function<void(error_code const&)> const& cb) , std::function<void(error_code const&)> const& cb)
{ {
TORRENT_UNUSED(bytes_transferred); TORRENT_UNUSED(bytes_transferred);

View File

@ -412,7 +412,6 @@ namespace aux {
#endif #endif
) )
, m_work(new io_service::work(m_io_service)) , m_work(new io_service::work(m_io_service))
, m_ip_notifier(create_ip_notifier(m_io_service))
#if TORRENT_USE_I2P #if TORRENT_USE_I2P
, m_i2p_conn(m_io_service) , m_i2p_conn(m_io_service)
#endif #endif
@ -589,9 +588,6 @@ namespace aux {
session_log(" done starting session"); session_log(" done starting session");
#endif #endif
m_ip_notifier->async_wait([this](error_code const& e)
{ this->wrap(&session_impl::on_ip_change, e); });
apply_settings_pack_impl(*pack, true); apply_settings_pack_impl(*pack, true);
// call update_* after settings set initialized // call update_* after settings set initialized
@ -606,6 +602,7 @@ namespace aux {
update_unchoke_limit(); update_unchoke_limit();
update_disk_threads(); update_disk_threads();
update_resolver_cache_timeout(); update_resolver_cache_timeout();
update_ip_notifier();
update_upnp(); update_upnp();
update_natpmp(); update_natpmp();
update_lsd(); update_lsd();
@ -885,11 +882,10 @@ namespace aux {
m_abort = true; m_abort = true;
error_code ec; error_code ec;
m_ip_notifier->cancel();
#if TORRENT_USE_I2P #if TORRENT_USE_I2P
m_i2p_conn.close(ec); m_i2p_conn.close(ec);
#endif #endif
stop_ip_notifier();
stop_lsd(); stop_lsd();
stop_upnp(); stop_upnp();
stop_natpmp(); stop_natpmp();
@ -1737,7 +1733,7 @@ namespace {
else else
session_log("received error on_ip_change: %d, %s", ec.value(), ec.message().c_str()); session_log("received error on_ip_change: %d, %s", ec.value(), ec.message().c_str());
#endif #endif
if (ec || m_abort) return; if (ec || m_abort || !m_ip_notifier) return;
m_ip_notifier->async_wait([this] (error_code const& e) m_ip_notifier->async_wait([this] (error_code const& e)
{ this->wrap(&session_impl::on_ip_change, e); }); { this->wrap(&session_impl::on_ip_change, e); });
reopen_network_sockets(session_handle::reopen_map_ports); reopen_network_sockets(session_handle::reopen_map_ports);
@ -5249,6 +5245,14 @@ namespace {
m_outgoing_sockets.update_proxy(proxy()); m_outgoing_sockets.update_proxy(proxy());
} }
void session_impl::update_ip_notifier()
{
if (m_settings.get_bool(settings_pack::enable_ip_notifier))
start_ip_notifier();
else
stop_ip_notifier();
}
void session_impl::update_upnp() void session_impl::update_upnp()
{ {
if (m_settings.get_bool(settings_pack::enable_upnp)) if (m_settings.get_bool(settings_pack::enable_upnp))
@ -6527,6 +6531,17 @@ namespace {
} }
#endif #endif
void session_impl::start_ip_notifier()
{
INVARIANT_CHECK;
if (m_ip_notifier) return;
m_ip_notifier = create_ip_notifier(m_io_service);
m_ip_notifier->async_wait([this](error_code const& e)
{ this->wrap(&session_impl::on_ip_change, e); });
}
void session_impl::start_lsd() void session_impl::start_lsd()
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
@ -6599,6 +6614,14 @@ namespace {
if (m_natpmp) m_natpmp->delete_mapping(handle); if (m_natpmp) m_natpmp->delete_mapping(handle);
} }
void session_impl::stop_ip_notifier()
{
if (!m_ip_notifier) return;
m_ip_notifier->cancel();
m_ip_notifier.reset();
}
void session_impl::stop_lsd() void session_impl::stop_lsd()
{ {
if (m_lsd) if (m_lsd)

View File

@ -199,6 +199,7 @@ constexpr int CLOSE_FILE_INTERVAL = 0;
SET(proxy_peer_connections, true, nullptr), SET(proxy_peer_connections, true, nullptr),
SET(auto_sequential, true, &session_impl::update_auto_sequential), SET(auto_sequential, true, &session_impl::update_auto_sequential),
SET(proxy_tracker_connections, true, nullptr), SET(proxy_tracker_connections, true, nullptr),
SET(enable_ip_notifier, true, &session_impl::update_ip_notifier),
}}); }});
aux::array<int_setting_entry_t, settings_pack::num_int_settings> const int_settings aux::array<int_setting_entry_t, settings_pack::num_int_settings> const int_settings