From 5480c081849ad4de1b2e01988161714347d62ef7 Mon Sep 17 00:00:00 2001 From: Alden Torres Date: Wed, 1 Nov 2017 05:51:51 -0400 Subject: [PATCH] enable/disable the internal ip notifier with new setting (#2487) --- include/libtorrent/aux_/session_impl.hpp | 3 ++ include/libtorrent/settings_pack.hpp | 10 +++++ simulation/test_session.cpp | 48 ++++++++++++++++++++++++ src/ip_notifier.cpp | 4 +- src/session_impl.cpp | 37 ++++++++++++++---- src/settings_pack.cpp | 1 + 6 files changed, 94 insertions(+), 9 deletions(-) diff --git a/include/libtorrent/aux_/session_impl.hpp b/include/libtorrent/aux_/session_impl.hpp index 5a0dc778c..6873927c5 100644 --- a/include/libtorrent/aux_/session_impl.hpp +++ b/include/libtorrent/aux_/session_impl.hpp @@ -614,10 +614,12 @@ namespace aux { , error_code const& e); #endif + void start_ip_notifier(); void start_lsd(); natpmp* start_natpmp(); upnp* start_upnp(); + void stop_ip_notifier(); void stop_lsd(); void stop_natpmp(); void stop_upnp(); @@ -715,6 +717,7 @@ namespace aux { void update_max_failcount(); void update_resolver_cache_timeout(); + void update_ip_notifier(); void update_upnp(); void update_natpmp(); void update_lsd(); diff --git a/include/libtorrent/settings_pack.hpp b/include/libtorrent/settings_pack.hpp index 613b9fe02..8b816731f 100644 --- a/include/libtorrent/settings_pack.hpp +++ b/include/libtorrent/settings_pack.hpp @@ -716,6 +716,16 @@ namespace libtorrent { // any. 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 }; diff --git a/simulation/test_session.cpp b/simulation/test_session.cpp index afa715dd2..7b33f0d13 100644 --- a/simulation/test_session.cpp +++ b/simulation/test_session.cpp @@ -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); +} diff --git a/src/ip_notifier.cpp b/src/ip_notifier.cpp index 990f3bf3d..2e103c38b 100644 --- a/src/ip_notifier.cpp +++ b/src/ip_notifier.cpp @@ -91,7 +91,7 @@ struct ip_change_notifier_impl final : ip_change_notifier { using namespace std::placeholders; 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 @@ -101,7 +101,7 @@ private: netlink::socket m_socket; std::array 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 const& cb) { TORRENT_UNUSED(bytes_transferred); diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 4cc2cb88a..391af5404 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -412,7 +412,6 @@ namespace aux { #endif ) , m_work(new io_service::work(m_io_service)) - , m_ip_notifier(create_ip_notifier(m_io_service)) #if TORRENT_USE_I2P , m_i2p_conn(m_io_service) #endif @@ -589,9 +588,6 @@ namespace aux { session_log(" done starting session"); #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); // call update_* after settings set initialized @@ -606,6 +602,7 @@ namespace aux { update_unchoke_limit(); update_disk_threads(); update_resolver_cache_timeout(); + update_ip_notifier(); update_upnp(); update_natpmp(); update_lsd(); @@ -885,11 +882,10 @@ namespace aux { m_abort = true; error_code ec; - m_ip_notifier->cancel(); - #if TORRENT_USE_I2P m_i2p_conn.close(ec); #endif + stop_ip_notifier(); stop_lsd(); stop_upnp(); stop_natpmp(); @@ -1737,7 +1733,7 @@ namespace { else session_log("received error on_ip_change: %d, %s", ec.value(), ec.message().c_str()); #endif - if (ec || m_abort) return; + if (ec || m_abort || !m_ip_notifier) return; m_ip_notifier->async_wait([this] (error_code const& e) { this->wrap(&session_impl::on_ip_change, e); }); reopen_network_sockets(session_handle::reopen_map_ports); @@ -5249,6 +5245,14 @@ namespace { 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() { if (m_settings.get_bool(settings_pack::enable_upnp)) @@ -6527,6 +6531,17 @@ namespace { } #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() { INVARIANT_CHECK; @@ -6599,6 +6614,14 @@ namespace { 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() { if (m_lsd) diff --git a/src/settings_pack.cpp b/src/settings_pack.cpp index ff757f02d..5d34eab44 100644 --- a/src/settings_pack.cpp +++ b/src/settings_pack.cpp @@ -199,6 +199,7 @@ constexpr int CLOSE_FILE_INTERVAL = 0; SET(proxy_peer_connections, true, nullptr), SET(auto_sequential, true, &session_impl::update_auto_sequential), SET(proxy_tracker_connections, true, nullptr), + SET(enable_ip_notifier, true, &session_impl::update_ip_notifier), }}); aux::array const int_settings