diff --git a/ChangeLog b/ChangeLog index dfe738f43..db6fee132 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,5 @@ + * pausing the session now also pauses checking torrents + * moved alert queue size limit into session_settings * added support for DHT rss feeds (storing only) * added support for RSS feeds * fixed up some edge cases in DHT routing table and improved unit test of it diff --git a/bindings/python/src/session.cpp b/bindings/python/src/session.cpp index 19aff8099..8bb0d7114 100644 --- a/bindings/python/src/session.cpp +++ b/bindings/python/src/session.cpp @@ -513,9 +513,9 @@ void bind_session() #ifndef TORRENT_NO_DEPRECATE .def("load_state", load_state1) .def("set_severity_level", allow_threads(&session::set_severity_level)) + .def("set_alert_queue_size_limit", allow_threads(&session::set_alert_queue_size_limit)) #endif .def("set_alert_mask", allow_threads(&session::set_alert_mask)) - .def("set_alert_queue_size_limit", allow_threads(&session::set_alert_queue_size_limit)) .def("pop_alert", allow_threads(&session::pop_alert)) .def("wait_for_alert", &wait_for_alert, return_internal_reference<>()) .def("add_extension", &add_extension) diff --git a/bindings/python/src/session_settings.cpp b/bindings/python/src/session_settings.cpp index b8e5882f4..7a2a53dec 100644 --- a/bindings/python/src/session_settings.cpp +++ b/bindings/python/src/session_settings.cpp @@ -138,6 +138,8 @@ void bind_session_settings() .def_readwrite("announce_double_nat", &session_settings::announce_double_nat) .def_readwrite("torrent_connect_boost", &session_settings::torrent_connect_boost) .def_readwrite("seeding_outgoing_connections", &session_settings::seeding_outgoing_connections) + .def_readwrite("no_connect_privileged_ports", &session_settings::no_connect_privileged_ports) + .def_readwrite("alert_queue_size", &session_settings::alert_queue_size) ; enum_("proxy_type") diff --git a/docs/manual.rst b/docs/manual.rst index cc187ab6d..a1b807159 100644 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -941,14 +941,13 @@ Changes the mask of which alerts to receive. By default only errors are reported See alerts_ for mor information on the alert categories. -pop_alert() wait_for_alert() set_alert_queue_size_limit() ---------------------------------------------------------- +pop_alert() wait_for_alert() +---------------------------- :: std::auto_ptr pop_alert(); alert const* wait_for_alert(time_duration max_wait); - size_t set_alert_queue_size_limit(size_t queue_size_limit_); ``pop_alert()`` is used to ask the session if any errors or events has occurred. With `set_alert_mask()`_ you can filter which alerts to receive through ``pop_alert()``. @@ -964,9 +963,8 @@ can be called and it can pop the alert independently. In the python binding, ``wait_for_alert`` takes the number of milliseconds to wait as an integer. -``set_alert_queue_size_limit()`` you can specify how many alerts can be awaiting for dispatching. -If this limit is reached, new incoming alerts can not be received until alerts are popped -by calling ``pop_alert``. Default value is 1000. +To control the max number of alerts that's queued by the session, see +``session_settings::alert_queue_size``. ``save_resume_data_alert`` and ``save_resume_data_failed_alert`` are always posted, regardelss of the alert mask. @@ -4243,6 +4241,9 @@ session_settings int torrent_connect_boost; bool seeding_outgoing_connections; + + bool no_connect_privileged_ports; + int alert_queue_size; }; ``version`` is automatically set to the libtorrent version you're using @@ -5058,6 +5059,14 @@ outgoing connections is high, and there are no or small benefits of doing so. For instance, if no nodes are behind a firewall or a NAT, seeds don't need to make outgoing connections. +if ``no_connect_privileged_ports`` is true (which is the default), libtorrent +will not connect to any peers on priviliged ports (<= 1023). This can mitigate +using bittorrent swarms for certain DDoS attacks. + +``alert_queue_size`` is the maximum number of alerts queued up internally. If +alerts are not popped, the queue will eventually fill up to this level. This +defaults to 1000. + pe_settings =========== @@ -5805,6 +5814,7 @@ is its synopsis: virtual std::string message() const = 0; virtual char const* what() const = 0; virtual int category() const = 0; + virtual bool discardable() const; virtual std::auto_ptr clone() const = 0; }; @@ -5837,6 +5847,10 @@ not include any information that might be bundled with the alert. ``clone()`` returns a pointer to a copy of the alert. +``discardable()`` determines whether or not an alert is allowed to be discarded +when the alert queue is full. There are a few alerts which may not be discared, +since they would break the user contract, such as ``save_resume_data_alert``. + ``message()`` generate a string describing the alert and the information bundled with it. This is mainly intended for debug and development use. It is not suitable to use this for applications that may be localized. Instead, handle each alert diff --git a/include/libtorrent/alert.hpp b/include/libtorrent/alert.hpp index 2acfb5295..f51c31c10 100644 --- a/include/libtorrent/alert.hpp +++ b/include/libtorrent/alert.hpp @@ -103,6 +103,7 @@ namespace libtorrent { virtual char const* what() const = 0; virtual std::string message() const = 0; virtual int category() const = 0; + virtual bool discardable() const { return true; } #ifndef TORRENT_NO_DEPRECATE TORRENT_DEPRECATED_PREFIX @@ -151,7 +152,7 @@ namespace libtorrent { private: std::deque m_alerts; mutable mutex m_mutex; - event m_condition; +// event m_condition; int m_alert_mask; size_t m_queue_size_limit; boost::function)> m_dispatch; diff --git a/include/libtorrent/alert_types.hpp b/include/libtorrent/alert_types.hpp index 436dd78a0..48629c5ea 100644 --- a/include/libtorrent/alert_types.hpp +++ b/include/libtorrent/alert_types.hpp @@ -121,6 +121,7 @@ namespace libtorrent const static int static_category = alert::storage_notification; virtual std::string message() const; + virtual bool discardable() const { return false; } boost::shared_array buffer; int piece; @@ -157,6 +158,7 @@ namespace libtorrent const static int static_category = alert::storage_notification; virtual std::string message() const; + virtual bool discardable() const { return false; } std::string name; int index; @@ -177,6 +179,7 @@ namespace libtorrent const static int static_category = alert::storage_notification; virtual std::string message() const; + virtual bool discardable() const { return false; } int index; error_code error; @@ -721,6 +724,7 @@ namespace libtorrent const static int static_category = alert::storage_notification; virtual std::string message() const { return torrent_alert::message() + " resume data generated"; } + virtual bool discardable() const { return false; } boost::shared_ptr resume_data; }; @@ -746,6 +750,7 @@ namespace libtorrent return torrent_alert::message() + " resume data was not generated: " + error.message(); } + virtual bool discardable() const { return false; } error_code error; @@ -939,6 +944,7 @@ namespace libtorrent const static int static_category = alert::status_notification | alert::error_notification; virtual std::string message() const; + virtual bool discardable() const { return false; } tcp::endpoint endpoint; error_code error; @@ -954,6 +960,7 @@ namespace libtorrent const static int static_category = alert::status_notification; virtual std::string message() const; + virtual bool discardable() const { return false; } tcp::endpoint endpoint; }; diff --git a/include/libtorrent/session.hpp b/include/libtorrent/session.hpp index 799f4f1ec..47daa8283 100644 --- a/include/libtorrent/session.hpp +++ b/include/libtorrent/session.hpp @@ -416,9 +416,11 @@ namespace libtorrent #ifndef TORRENT_NO_DEPRECATE TORRENT_DEPRECATED_PREFIX void set_severity_level(alert::severity_t s) TORRENT_DEPRECATED; + + TORRENT_DEPRECATED_PREFIX + size_t set_alert_queue_size_limit(size_t queue_size_limit_) TORRENT_DEPRECATED; #endif void set_alert_mask(int m); - size_t set_alert_queue_size_limit(size_t queue_size_limit_); alert const* wait_for_alert(time_duration max_wait); void set_alert_dispatch(boost::function)> const& fun); diff --git a/include/libtorrent/session_settings.hpp b/include/libtorrent/session_settings.hpp index f3658c04f..b52d7a5b4 100644 --- a/include/libtorrent/session_settings.hpp +++ b/include/libtorrent/session_settings.hpp @@ -254,6 +254,7 @@ namespace libtorrent , torrent_connect_boost(10) , seeding_outgoing_connections(true) , no_connect_privileged_ports(true) + , alert_queue_size(1000) {} // libtorrent version. Used for forward binary compatibility @@ -1016,6 +1017,9 @@ namespace libtorrent // connections to peers whose port is < 1024. This is a safety // precaution to avoid being part of a DDoS attack bool no_connect_privileged_ports; + + // the max alert queue size + int alert_queue_size; }; #ifndef TORRENT_DISABLE_DHT diff --git a/src/alert.cpp b/src/alert.cpp index 62093c997..94de213b9 100644 --- a/src/alert.cpp +++ b/src/alert.cpp @@ -403,10 +403,10 @@ namespace libtorrent { return; } - if (m_alerts.size() >= m_queue_size_limit) return; + if (m_alerts.size() >= m_queue_size_limit && alert_.discardable()) return; m_alerts.push_back(alert_.clone().release()); - m_condition.signal(lock); - m_condition.clear(lock); +// m_condition.signal(lock); +// m_condition.clear(lock); } std::auto_ptr alert_manager::get() diff --git a/src/session.cpp b/src/session.cpp index 1ee8969eb..358b18c34 100644 --- a/src/session.cpp +++ b/src/session.cpp @@ -94,6 +94,9 @@ namespace libtorrent session_settings min_memory_usage() { session_settings set; + + set.alert_queue_size = 100; + // setting this to a low limit, means more // peers are more likely to request from the // same piece. Which means fewer partial @@ -168,6 +171,8 @@ namespace libtorrent { session_settings set; + set.alert_queue_size = 10000; + // allow 500 files open at a time set.file_pool_size = 500; @@ -903,6 +908,11 @@ namespace libtorrent TORRENT_SYNC_CALL_RET(int, num_connections); return r; } + + void session::set_alert_dispatch(boost::function)> const& fun) + { + TORRENT_ASYNC_CALL1(set_alert_dispatch, fun); + } #endif // TORRENT_NO_DEPRECATE std::auto_ptr session::pop_alert() @@ -910,11 +920,6 @@ namespace libtorrent return m_impl->pop_alert(); } - void session::set_alert_dispatch(boost::function)> const& fun) - { - TORRENT_ASYNC_CALL1(set_alert_dispatch, fun); - } - alert const* session::wait_for_alert(time_duration max_wait) { return m_impl->wait_for_alert(max_wait); @@ -925,13 +930,13 @@ namespace libtorrent TORRENT_ASYNC_CALL1(set_alert_mask, m); } +#ifndef TORRENT_NO_DEPRECATE size_t session::set_alert_queue_size_limit(size_t queue_size_limit_) { TORRENT_SYNC_CALL_RET1(size_t, set_alert_queue_size_limit, queue_size_limit_); return r; } -#ifndef TORRENT_NO_DEPRECATE void session::set_severity_level(alert::severity_t s) { int m = 0; diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 2436ac3bf..c8cdd20f5 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -352,6 +352,8 @@ namespace aux { TORRENT_SETTING(boolean, announce_double_nat) TORRENT_SETTING(integer, torrent_connect_boost) TORRENT_SETTING(boolean, seeding_outgoing_connections) + TORRENT_SETTING(boolean, no_connect_privileged_ports) + TORRENT_SETTING(integer, alert_queue_size) }; #undef TORRENT_SETTING @@ -1515,6 +1517,9 @@ namespace aux { } } + if (m_settings.alert_queue_size != s.alert_queue_size) + m_alerts.set_alert_queue_size_limit(s.alert_queue_size); + m_settings = s; update_rate_settings(); @@ -2007,6 +2012,14 @@ namespace aux { { TORRENT_ASSERT(is_network_thread()); + if (m_paused) + { +#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) + (*m_logger) << time_now_string() << " <== INCOMING CONNECTION [ ignored, paused ]\n"; +#endif + return; + } + error_code ec; // we got a connection request! tcp::endpoint endp = s->remote_endpoint(ec); @@ -4411,10 +4424,13 @@ namespace aux { m_alerts.set_alert_mask(m); } +#ifndef TORRENT_NO_DEPRECATE size_t session_impl::set_alert_queue_size_limit(size_t queue_size_limit_) { + m_settings.alert_queue_size = queue_size_limit_; return m_alerts.set_alert_queue_size_limit(queue_size_limit_); } +#endif void session_impl::start_lsd() { diff --git a/src/torrent.cpp b/src/torrent.cpp index b159f839a..80a58fb10 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -5924,7 +5924,8 @@ namespace libtorrent && (m_allow_peers || m_auto_managed) && !has_error() && !m_abort - && !m_graceful_pause_mode; + && !m_graceful_pause_mode + && !m_ses.is_paused(); } void torrent::flush_cache() @@ -5953,7 +5954,6 @@ namespace libtorrent INVARIANT_CHECK; if (!m_allow_peers) return; - bool checking_files = should_check_files(); if (!graceful) m_allow_peers = false; m_announce_to_dht = false; m_announce_to_trackers = false; @@ -5964,13 +5964,6 @@ namespace libtorrent if (!m_ses.is_paused() || (prev_graceful && !m_graceful_pause_mode)) do_pause(); - if (checking_files && !should_check_files()) - { - // stop checking - m_storage->abort_disk_io(); - dequeue_torrent_check(); - set_state(torrent_status::queued_for_checking); - } } void torrent::do_pause() @@ -6050,6 +6043,14 @@ namespace libtorrent } stop_announcing(); + + if (m_queued_for_checking && !should_check_files()) + { + // stop checking + m_storage->abort_disk_io(); + dequeue_torrent_check(); + set_state(torrent_status::queued_for_checking); + } } #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING || defined TORRENT_LOGGING @@ -6092,11 +6093,6 @@ namespace libtorrent { do_resume(); } - - if (!checking_files && should_check_files()) - queue_torrent_check(); - else if (checking_files && !should_check_files()) - dequeue_torrent_check(); } void torrent::resume() @@ -6115,8 +6111,6 @@ namespace libtorrent m_announce_to_lsd = true; if (!m_ses.is_paused()) m_graceful_pause_mode = false; do_resume(); - if (!checking_files && should_check_files()) - queue_torrent_check(); } void torrent::do_resume() @@ -6144,6 +6138,8 @@ namespace libtorrent m_started = time_now(); clear_error(); start_announcing(); + if (!m_queued_for_checking && should_check_files()) + queue_torrent_check(); } void torrent::update_tracker_timer(ptime now)