diff --git a/ChangeLog b/ChangeLog index 644ad030f..b46890030 100644 --- a/ChangeLog +++ b/ChangeLog @@ -83,6 +83,7 @@ incoming connection * added more detailed instrumentation of the disk I/O thread + * fixed broadcast_lsd option * fixed udp-socket race condition when using a proxy * end-game mode optimizations * fixed bug in udp_socket causing it to issue two simultaneous async. read operations diff --git a/docs/manual.rst b/docs/manual.rst index 653a1cf5b..5c2614d4e 100644 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -4985,7 +4985,9 @@ be changed individually later using if ``broadcast_lsd`` is set to true, the local peer discovery (or Local Service Discovery) will not only use IP multicast, but also broadcast its messages. This can be useful when running on networks -that don't support multicast. It's off by default since it's inefficient. +that don't support multicast. Since broadcast messages might be +expensive and disruptive on networks, only every 8th announce uses +broadcast. ``enable_outgoing_utp``, ``enable_incoming_utp``, ``enable_outgoing_tcp``, ``enable_incoming_tcp`` all determines if libtorrent should attempt to make diff --git a/include/libtorrent/aux_/session_impl.hpp b/include/libtorrent/aux_/session_impl.hpp index e2a8d83c1..58eb07e1c 100644 --- a/include/libtorrent/aux_/session_impl.hpp +++ b/include/libtorrent/aux_/session_impl.hpp @@ -327,7 +327,7 @@ namespace libtorrent torrent_handle find_torrent_handle(sha1_hash const& info_hash); - void announce_lsd(sha1_hash const& ih); + void announce_lsd(sha1_hash const& ih, bool broadcast = false); void save_state(entry* e, boost::uint32_t flags) const; void load_state(lazy_entry const* e); diff --git a/include/libtorrent/lsd.hpp b/include/libtorrent/lsd.hpp index 72c4fcca4..9e746c8a6 100644 --- a/include/libtorrent/lsd.hpp +++ b/include/libtorrent/lsd.hpp @@ -61,11 +61,9 @@ public: // void rebind(address const& listen_interface); - void announce(sha1_hash const& ih, int listen_port); + void announce(sha1_hash const& ih, int listen_port, bool broadcast = false); void close(); - void use_broadcast(bool b); - private: void resend_announce(error_code const& e, std::string msg); diff --git a/include/libtorrent/session_settings.hpp b/include/libtorrent/session_settings.hpp index c422a9dba..1fa037521 100644 --- a/include/libtorrent/session_settings.hpp +++ b/include/libtorrent/session_settings.hpp @@ -226,7 +226,7 @@ namespace libtorrent , strict_end_game_mode(true) , default_peer_upload_rate(0) , default_peer_download_rate(0) - , broadcast_lsd(false) + , broadcast_lsd(true) , enable_outgoing_utp(true) , enable_incoming_utp(true) , enable_outgoing_tcp(true) diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index 9b06102a2..60c0bac63 100644 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -1279,6 +1279,10 @@ namespace libtorrent // and set this to false. We only do this once to get // the torrent kick-started bool m_need_connect_boost:1; + + // rotating sequence number for LSD announces sent out. + // used to only use IP broadcast for every 8th lsd announce + boost::uint8_t m_lsd_seq:3; }; } diff --git a/src/broadcast_socket.cpp b/src/broadcast_socket.cpp index 40ac8d964..c1125365a 100644 --- a/src/broadcast_socket.cpp +++ b/src/broadcast_socket.cpp @@ -252,7 +252,7 @@ namespace libtorrent for (std::list::iterator i = m_unicast_sockets.begin() , end(m_unicast_sockets.end()); i != end; ++i) { - if (i->socket) continue; + if (!i->socket) continue; i->socket->set_option(option, ec); } } diff --git a/src/lsd.cpp b/src/lsd.cpp index 12073f0b4..0c8aa2b88 100644 --- a/src/lsd.cpp +++ b/src/lsd.cpp @@ -82,7 +82,7 @@ lsd::lsd(io_service& ios, address const& listen_interface lsd::~lsd() {} -void lsd::announce(sha1_hash const& ih, int listen_port) +void lsd::announce(sha1_hash const& ih, int listen_port, bool broadcast) { if (m_disabled) return; @@ -98,6 +98,7 @@ void lsd::announce(sha1_hash const& ih, int listen_port) m_retry_count = 1; error_code ec; + m_socket.enable_ip_broadcast(broadcast); m_socket.send(msg, msg_len, ec); if (ec) { @@ -117,7 +118,7 @@ void lsd::announce(sha1_hash const& ih, int listen_port) #if defined TORRENT_ASIO_DEBUGGING add_outstanding_async("lsd::resend_announce"); #endif - m_broadcast_timer.expires_from_now(milliseconds(250 * m_retry_count), ec); + m_broadcast_timer.expires_from_now(seconds(2 * m_retry_count), ec); m_broadcast_timer.async_wait(boost::bind(&lsd::resend_announce, self(), _1 , std::string(msg))); } @@ -130,16 +131,17 @@ void lsd::resend_announce(error_code const& e, std::string msg) if (e) return; error_code ec; + // don't broadcast resends + m_socket.enable_ip_broadcast(false); m_socket.send(msg.c_str(), int(msg.size()), ec); ++m_retry_count; - if (m_retry_count >= 5) - return; + if (m_retry_count >= 3) return; #if defined TORRENT_ASIO_DEBUGGING add_outstanding_async("lsd::resend_announce"); #endif - m_broadcast_timer.expires_from_now(milliseconds(250 * m_retry_count), ec); + m_broadcast_timer.expires_from_now(seconds(2 * m_retry_count), ec); m_broadcast_timer.async_wait(boost::bind(&lsd::resend_announce, self(), _1, msg)); } @@ -234,8 +236,3 @@ void lsd::close() m_callback.clear(); } -void lsd::use_broadcast(bool b) -{ - m_socket.enable_ip_broadcast(b); -} - diff --git a/src/session_impl.cpp b/src/session_impl.cpp index b63a0d88e..4f68e0364 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -1124,9 +1124,6 @@ namespace aux { if (m_settings.connection_speed < 0) m_settings.connection_speed = 200; - if (m_settings.broadcast_lsd && m_lsd) - m_lsd->use_broadcast(true); - update_disk_thread_settings(); settings = e->dict_find_list("feeds"); @@ -1669,8 +1666,6 @@ namespace aux { m_listen_sockets.clear(); } if (m_settings.connection_speed < 0) m_settings.connection_speed = 200; - if (m_settings.broadcast_lsd && m_lsd) - m_lsd->use_broadcast(true); if (update_disk_io_thread) update_disk_thread_settings(); @@ -4171,11 +4166,11 @@ namespace aux { return m_listen_sockets.front().external_port; } - void session_impl::announce_lsd(sha1_hash const& ih) + void session_impl::announce_lsd(sha1_hash const& ih, bool broadcast) { // use internal listen port for local peers if (m_lsd.get()) - m_lsd->announce(ih, m_listen_interface.port()); + m_lsd->announce(ih, m_listen_interface.port(), broadcast); } void session_impl::on_lsd_peer(tcp::endpoint peer, sha1_hash const& ih) @@ -4782,8 +4777,6 @@ namespace aux { m_lsd = new lsd(m_io_service , m_listen_interface.address() , boost::bind(&session_impl::on_lsd_peer, this, _1, _2)); - if (m_settings.broadcast_lsd) - m_lsd->use_broadcast(true); } natpmp* session_impl::start_natpmp() diff --git a/src/torrent.cpp b/src/torrent.cpp index c91dae71e..080965106 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -403,6 +403,7 @@ namespace libtorrent , m_interface_index(0) , m_graceful_pause_mode(false) , m_need_connect_boost(true) + , m_lsd_seq(0) { if (!m_url.empty() && m_uuid.empty()) m_uuid = m_url; @@ -1679,7 +1680,9 @@ namespace libtorrent if (is_paused()) return; // announce with the local discovery service - m_ses.announce_lsd(m_torrent_file->info_hash()); + m_ses.announce_lsd(m_torrent_file->info_hash() + , m_ses.settings().broadcast_lsd && m_lsd_seq == 0); + ++m_lsd_seq; } #ifndef TORRENT_DISABLE_DHT diff --git a/test/setup_transfer.cpp b/test/setup_transfer.cpp index 712d242cc..deddadd25 100644 --- a/test/setup_transfer.cpp +++ b/test/setup_transfer.cpp @@ -251,14 +251,17 @@ setup_transfer(session* ses1, session* ses2, session* ses3 , bool clear_files, bool use_metadata_transfer, bool connect_peers , std::string suffix, int piece_size , boost::intrusive_ptr* torrent, bool super_seeding - , add_torrent_params const* p) + , add_torrent_params const* p, bool stop_lsd) { assert(ses1); assert(ses2); - ses1->stop_lsd(); - ses2->stop_lsd(); - if (ses3) ses3->stop_lsd(); + if (stop_lsd) + { + ses1->stop_lsd(); + ses2->stop_lsd(); + if (ses3) ses3->stop_lsd(); + } session_settings sess_set = ses1->settings(); if (ses3) sess_set.allow_multiple_connections_per_ip = true; diff --git a/test/setup_transfer.hpp b/test/setup_transfer.hpp index 771e94b9e..a5e236997 100644 --- a/test/setup_transfer.hpp +++ b/test/setup_transfer.hpp @@ -61,7 +61,7 @@ setup_transfer(libtorrent::session* ses1, libtorrent::session* ses2 , libtorrent::session* ses3, bool clear_files, bool use_metadata_transfer = true , bool connect = true, std::string suffix = "", int piece_size = 16 * 1024 , boost::intrusive_ptr* torrent = 0, bool super_seeding = false - , libtorrent::add_torrent_params const* p = 0); + , libtorrent::add_torrent_params const* p = 0, bool stop_lsd = true); int start_web_server(bool ssl = false, bool chunked = false); void stop_web_server(); diff --git a/test/test_lsd.cpp b/test/test_lsd.cpp index ab193b061..c1ee6b1e7 100644 --- a/test/test_lsd.cpp +++ b/test/test_lsd.cpp @@ -58,7 +58,8 @@ void test_lsd() torrent_handle tor2; using boost::tuples::ignore; - boost::tie(tor1, tor2, ignore) = setup_transfer(&ses1, &ses2, 0, true, false, false, "_lsd"); + boost::tie(tor1, tor2, ignore) = setup_transfer(&ses1, &ses2, 0, true, false, false, "_lsd" + , 16 * 1024, 0, false, 0, false); for (int i = 0; i < 30; ++i) {