move the DHT rate limiter into the dht_tracker class and remove the rate_limited_udp_socket type. This further simplifies the udp socket (preparing for moving it into the listen_socket structure)
This commit is contained in:
parent
e2392017bc
commit
297b8943d0
|
@ -635,7 +635,9 @@ namespace libtorrent
|
|||
void update_connection_speed();
|
||||
void update_queued_disk_bytes();
|
||||
void update_alert_queue_size();
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
void update_dht_upload_rate_limit();
|
||||
#endif
|
||||
void update_disk_threads();
|
||||
void update_network_threads();
|
||||
void update_cache_buffer_chunk_size();
|
||||
|
@ -1031,7 +1033,7 @@ namespace libtorrent
|
|||
// but for the udp port used by the DHT.
|
||||
int m_external_udp_port;
|
||||
|
||||
rate_limited_udp_socket m_udp_socket;
|
||||
udp_socket m_udp_socket;
|
||||
libtorrent::utp_socket_manager m_utp_socket_manager;
|
||||
|
||||
#ifdef TORRENT_USE_OPENSSL
|
||||
|
|
|
@ -71,7 +71,7 @@ namespace libtorrent { namespace dht
|
|||
, udp_socket_observer
|
||||
, boost::enable_shared_from_this<dht_tracker>
|
||||
{
|
||||
dht_tracker(dht_observer* observer, rate_limited_udp_socket& sock
|
||||
dht_tracker(dht_observer* observer, udp_socket& sock
|
||||
, dht_settings const& settings, counters& cnt
|
||||
, dht_storage_constructor_type storage_constructor
|
||||
, entry const& state);
|
||||
|
@ -155,7 +155,7 @@ namespace libtorrent { namespace dht
|
|||
|
||||
counters& m_counters;
|
||||
node m_dht;
|
||||
rate_limited_udp_socket& m_sock;
|
||||
udp_socket& m_sock;
|
||||
dht_logger* m_log;
|
||||
|
||||
std::vector<char> m_send_buf;
|
||||
|
@ -170,6 +170,10 @@ namespace libtorrent { namespace dht
|
|||
|
||||
// used to resolve hostnames for nodes
|
||||
udp::resolver m_host_resolver;
|
||||
|
||||
// state for the send rate limit
|
||||
int m_send_quota;
|
||||
time_point m_last_tick;
|
||||
};
|
||||
}}
|
||||
|
||||
|
|
|
@ -1406,6 +1406,7 @@ namespace libtorrent
|
|||
, block_ratelimit(5)
|
||||
, read_only(false)
|
||||
, item_lifetime(0)
|
||||
, upload_rate_limit(8000)
|
||||
{}
|
||||
|
||||
// the maximum number of peers to send in a reply to ``get_peers``
|
||||
|
@ -1507,6 +1508,11 @@ namespace libtorrent
|
|||
// the number of seconds a immutable/mutable item will be expired.
|
||||
// default is 0, means never expires.
|
||||
int item_lifetime;
|
||||
|
||||
// the number of bytes per second (on average) the DHT is allowed to send.
|
||||
// If the incoming requests causes to many bytes to be sent in responses,
|
||||
// incoming requests will be dropped until the quota has been replenished.
|
||||
int upload_rate_limit;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1248,11 +1248,15 @@ namespace libtorrent
|
|||
deprecated4,
|
||||
#endif
|
||||
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
// ``dht_upload_rate_limit`` sets the rate limit on the DHT. This is
|
||||
// specified in bytes per second and defaults to 4000. For busy boxes
|
||||
// with lots of torrents that requires more DHT traffic, this should
|
||||
// be raised.
|
||||
dht_upload_rate_limit,
|
||||
#else
|
||||
deprecated7,
|
||||
#endif
|
||||
|
||||
// ``unchoke_slots_limit`` is the max number of unchoked peers in the
|
||||
// session. The number of unchoke slots may be ignored depending on
|
||||
|
|
|
@ -309,21 +309,6 @@ namespace libtorrent
|
|||
int m_outstanding_socks;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct rate_limited_udp_socket : public udp_socket
|
||||
{
|
||||
rate_limited_udp_socket(io_service& ios);
|
||||
void set_rate_limit(int limit) { m_rate_limit = limit; }
|
||||
bool send(udp::endpoint const& ep, char const* p, int len
|
||||
, error_code& ec, int flags = 0);
|
||||
bool has_quota();
|
||||
|
||||
private:
|
||||
|
||||
int m_rate_limit;
|
||||
int m_quota;
|
||||
time_point m_last_tick;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -49,6 +49,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/version.hpp"
|
||||
#include "libtorrent/time.hpp"
|
||||
#include "libtorrent/performance_counters.hpp" // for counters
|
||||
#include "libtorrent/aux_/time.hpp"
|
||||
|
||||
#include "libtorrent/aux_/disable_warnings_push.hpp"
|
||||
|
||||
|
@ -89,7 +90,7 @@ namespace libtorrent { namespace dht
|
|||
// class that puts the networking and the kademlia node in a single
|
||||
// unit and connecting them together.
|
||||
dht_tracker::dht_tracker(dht_observer* observer
|
||||
, rate_limited_udp_socket& sock
|
||||
, udp_socket& sock
|
||||
, dht_settings const& settings
|
||||
, counters& cnt
|
||||
, dht_storage_constructor_type storage_constructor
|
||||
|
@ -104,6 +105,8 @@ namespace libtorrent { namespace dht
|
|||
, m_settings(settings)
|
||||
, m_abort(false)
|
||||
, m_host_resolver(sock.get_io_service())
|
||||
, m_send_quota(settings.upload_rate_limit)
|
||||
, m_last_tick(aux::time_now())
|
||||
{
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
m_log->log(dht_logger::tracker, "starting DHT tracker with node id: %s"
|
||||
|
@ -406,10 +409,18 @@ namespace libtorrent { namespace dht
|
|||
|
||||
bool dht_tracker::has_quota()
|
||||
{
|
||||
return m_sock.has_quota();
|
||||
time_point now = clock_type::now();
|
||||
time_duration delta = now - m_last_tick;
|
||||
m_last_tick = now;
|
||||
// add any new quota we've accrued since last time
|
||||
m_send_quota += boost::uint64_t(m_settings.upload_rate_limit)
|
||||
* total_microseconds(delta) / 1000000;
|
||||
return m_send_quota > 0;
|
||||
}
|
||||
|
||||
bool dht_tracker::send_packet(libtorrent::entry& e, udp::endpoint const& addr, int send_flags)
|
||||
// TODO: 4 do we need the flags here?
|
||||
bool dht_tracker::send_packet(libtorrent::entry& e, udp::endpoint const& addr
|
||||
, int send_flags)
|
||||
{
|
||||
using libtorrent::bencode;
|
||||
using libtorrent::entry;
|
||||
|
@ -420,10 +431,26 @@ namespace libtorrent { namespace dht
|
|||
|
||||
m_send_buf.clear();
|
||||
bencode(std::back_inserter(m_send_buf), e);
|
||||
error_code ec;
|
||||
|
||||
bool ret = m_sock.send(addr, &m_send_buf[0], int(m_send_buf.size()), ec, send_flags);
|
||||
if (!ret || ec)
|
||||
// update the quota. We won't prevent the packet to be sent if we exceed
|
||||
// the quota, we'll just (potentially) block the next incoming request.
|
||||
time_point const now = clock_type::now();
|
||||
time_duration const delta = now - m_last_tick;
|
||||
m_last_tick = now;
|
||||
|
||||
// add any new quota we've accrued since last time
|
||||
m_send_quota += boost::uint64_t(m_settings.upload_rate_limit)
|
||||
* total_microseconds(delta) / 1000000;
|
||||
|
||||
// allow 3 seconds worth of burst
|
||||
if (m_send_quota > 3 * m_settings.upload_rate_limit)
|
||||
m_send_quota = 3 * m_settings.upload_rate_limit;
|
||||
|
||||
m_send_quota -= m_send_buf.size();
|
||||
|
||||
error_code ec;
|
||||
m_sock.send(addr, &m_send_buf[0], int(m_send_buf.size()), ec, send_flags);
|
||||
if (ec)
|
||||
{
|
||||
m_counters.inc_stats_counter(counters::dht_messages_out_dropped);
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
|
|
|
@ -204,10 +204,6 @@ namespace libtorrent
|
|||
// unchoke many peers
|
||||
set.set_int(settings_pack::unchoke_slots_limit, 2000);
|
||||
|
||||
// we need more DHT capacity to ping more peers
|
||||
// candidates before trying to connect
|
||||
set.set_int(settings_pack::dht_upload_rate_limit, 20000);
|
||||
|
||||
// use 1 GB of cache
|
||||
set.set_int(settings_pack::cache_size, 32768 * 2);
|
||||
set.set_bool(settings_pack::use_read_cache, true);
|
||||
|
|
|
@ -438,7 +438,6 @@ namespace aux {
|
|||
#if TORRENT_USE_ASSERTS
|
||||
m_posting_torrent_updates = false;
|
||||
#endif
|
||||
m_udp_socket.set_rate_limit(m_settings.get_int(settings_pack::dht_upload_rate_limit));
|
||||
|
||||
m_udp_socket.subscribe(&m_utp_socket_manager);
|
||||
m_udp_socket.subscribe(this);
|
||||
|
@ -6067,10 +6066,15 @@ retry:
|
|||
|| m_settings.get_int(settings_pack::unchoke_slots_limit) < 0;
|
||||
}
|
||||
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
void session_impl::update_dht_upload_rate_limit()
|
||||
{
|
||||
m_udp_socket.set_rate_limit(m_settings.get_int(settings_pack::dht_upload_rate_limit));
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
m_dht_settings.upload_rate_limit
|
||||
= m_settings.get_int(settings_pack::dht_upload_rate_limit);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
void session_impl::update_disk_threads()
|
||||
{
|
||||
|
|
|
@ -297,7 +297,7 @@ namespace libtorrent
|
|||
SET(download_rate_limit, 0, &session_impl::update_download_rate),
|
||||
DEPRECATED_SET(local_upload_rate_limit, 0, &session_impl::update_local_upload_rate),
|
||||
DEPRECATED_SET(local_download_rate_limit, 0, &session_impl::update_local_download_rate),
|
||||
SET(dht_upload_rate_limit, 4000, &session_impl::update_dht_upload_rate_limit),
|
||||
DEPRECATED_SET(dht_upload_rate_limit, 4000, &session_impl::update_dht_upload_rate_limit),
|
||||
SET(unchoke_slots_limit, 8, &session_impl::update_unchoke_limit),
|
||||
DEPRECATED_SET(half_open_limit, 0, 0),
|
||||
SET(connections_limit, 200, &session_impl::update_connections_limit),
|
||||
|
|
|
@ -1413,44 +1413,3 @@ void udp_socket::drain_queue()
|
|||
}
|
||||
}
|
||||
|
||||
rate_limited_udp_socket::rate_limited_udp_socket(io_service& ios)
|
||||
: udp_socket(ios)
|
||||
, m_rate_limit(8000)
|
||||
, m_quota(8000)
|
||||
, m_last_tick(aux::time_now())
|
||||
{
|
||||
}
|
||||
|
||||
bool rate_limited_udp_socket::has_quota()
|
||||
{
|
||||
time_point now = clock_type::now();
|
||||
time_duration delta = now - m_last_tick;
|
||||
m_last_tick = now;
|
||||
// add any new quota we've accrued since last time
|
||||
m_quota += boost::uint64_t(m_rate_limit) * total_microseconds(delta) / 1000000;
|
||||
return m_quota > 0;
|
||||
}
|
||||
|
||||
bool rate_limited_udp_socket::send(udp::endpoint const& ep, char const* p
|
||||
, int len, error_code& ec, int flags)
|
||||
{
|
||||
time_point now = clock_type::now();
|
||||
time_duration delta = now - m_last_tick;
|
||||
m_last_tick = now;
|
||||
|
||||
// add any new quota we've accrued since last time
|
||||
m_quota += boost::uint64_t(m_rate_limit) * total_microseconds(delta) / 1000000;
|
||||
|
||||
// allow 3 seconds worth of burst
|
||||
if (m_quota > 3 * m_rate_limit) m_quota = 3 * m_rate_limit;
|
||||
|
||||
// if there's no quota, and it's OK to drop, just
|
||||
// drop the packet
|
||||
if (m_quota < 0 && (flags & dont_drop) == 0) return false;
|
||||
|
||||
m_quota -= len;
|
||||
if (m_quota < 0) m_quota = 0;
|
||||
udp_socket::send(ep, p, len, ec, flags);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue