forked from premiere/premiere-libtorrent
UDP tracker optimization
This commit is contained in:
parent
abfc92de35
commit
8c02d04d2e
|
@ -101,6 +101,7 @@
|
|||
* support disk I/O priority settings
|
||||
* added info_hash to torrent_deleted_alert
|
||||
* improved LSD performance and made the interval configurable
|
||||
* improved UDP tracker support by caching connect tokens
|
||||
|
||||
release 0.14.9
|
||||
|
||||
|
|
|
@ -107,6 +107,7 @@ void bind_session_settings()
|
|||
.def_readwrite("drop_skipped_requests", &session_settings::drop_skipped_requests)
|
||||
.def_readwrite("low_prio_disk", &session_settings::low_prio_disk)
|
||||
.def_readwrite("local_service_announce_interval", &session_settings::local_service_announce_interval)
|
||||
.def_readwrite("udp_tracker_token_expiry", &session_settings::udp_tracker_token_expiry)
|
||||
.def_readwrite("volatile_read_cache", &session_settings::volatile_read_cache)
|
||||
.def_readwrite("guided_read_cache", &guided_read_cache)
|
||||
;
|
||||
|
|
|
@ -3722,6 +3722,8 @@ session_settings
|
|||
|
||||
bool low_prio_disk;
|
||||
int local_service_announce_interval;
|
||||
|
||||
int udp_tracker_token_expiry;
|
||||
bool volatile_read_cache;
|
||||
bool guided_read_cache;
|
||||
bool default_min_cache_age;
|
||||
|
@ -4219,6 +4221,13 @@ bound on the time a cache line stays in the cache is an attempt
|
|||
to avoid swapping the same pieces in and out of the cache in case
|
||||
there is a shortage of spare cache space.
|
||||
|
||||
``udp_tracker_token_expiry`` is the number of seconds libtorrent
|
||||
will keep UDP tracker connection tokens around for. This is specified
|
||||
to be 60 seconds, and defaults to that. The higher this value is, the
|
||||
fewer packets have to be sent to the UDP tracker. In order for higher
|
||||
values to work, the tracker needs to be configured to match the
|
||||
expiration time for tokens.
|
||||
|
||||
pe_settings
|
||||
===========
|
||||
|
||||
|
|
|
@ -187,6 +187,7 @@ namespace libtorrent
|
|||
, drop_skipped_requests(false)
|
||||
, low_prio_disk(true)
|
||||
, local_service_announce_interval(5 * 60)
|
||||
, udp_tracker_token_expiry(60)
|
||||
, volatile_read_cache(false)
|
||||
, guided_read_cache(true)
|
||||
, default_cache_min_age(1)
|
||||
|
@ -694,6 +695,11 @@ namespace libtorrent
|
|||
// torrents. Defaults to 5 minutes
|
||||
int local_service_announce_interval;
|
||||
|
||||
// the number of seconds a connection ID received
|
||||
// from a UDP tracker is valid for. This is specified
|
||||
// as 60 seconds
|
||||
int udp_tracker_token_expiry;
|
||||
|
||||
// if this is set to true, any block read from the
|
||||
// disk cache will be dropped from the cache immediately
|
||||
// following. This may be useful if the block is not
|
||||
|
|
|
@ -114,10 +114,17 @@ namespace libtorrent
|
|||
std::list<udp::endpoint> m_endpoints;
|
||||
|
||||
int m_transaction_id;
|
||||
boost::int64_t m_connection_id;
|
||||
aux::session_impl const& m_ses;
|
||||
int m_attempts;
|
||||
|
||||
struct connection_cache_entry
|
||||
{
|
||||
boost::int64_t connection_id;
|
||||
ptime expires;
|
||||
};
|
||||
|
||||
static std::map<address, connection_cache_entry> m_connection_cache;
|
||||
|
||||
action_t m_state;
|
||||
};
|
||||
|
||||
|
|
|
@ -285,7 +285,13 @@ namespace aux {
|
|||
TORRENT_SETTING(integer, max_suggest_pieces)
|
||||
TORRENT_SETTING(boolean, drop_skipped_requests)
|
||||
TORRENT_SETTING(boolean, low_prio_disk)
|
||||
TORRENT_SETTING(boolean, local_service_announce_interval)
|
||||
TORRENT_SETTING(integer, local_service_announce_interval)
|
||||
TORRENT_SETTING(integer, udp_tracker_token_expiry)
|
||||
TORRENT_SETTING(boolean, volatile_read_cache)
|
||||
TORRENT_SETTING(boolean, guided_read_cache)
|
||||
TORRENT_SETTING(integer, default_cache_min_age)
|
||||
TORRENT_SETTING(integer, num_optimistic_unchoke_slots)
|
||||
TORRENT_SETTING(boolean, no_atime_storage)
|
||||
};
|
||||
|
||||
#undef TORRENT_SETTING
|
||||
|
|
|
@ -94,6 +94,9 @@ udp_socket::~udp_socket()
|
|||
void udp_socket::send(udp::endpoint const& ep, char const* p, int len, error_code& ec)
|
||||
{
|
||||
CHECK_MAGIC;
|
||||
|
||||
TORRENT_ASSERT(is_open());
|
||||
|
||||
// if the sockets are closed, the udp_socket is closing too
|
||||
if (!is_open()) return;
|
||||
|
||||
|
|
|
@ -59,6 +59,9 @@ using boost::bind;
|
|||
namespace libtorrent
|
||||
{
|
||||
|
||||
std::map<address, udp_tracker_connection::connection_cache_entry>
|
||||
udp_tracker_connection::m_connection_cache;
|
||||
|
||||
udp_tracker_connection::udp_tracker_connection(
|
||||
io_service& ios
|
||||
, connection_queue& cc
|
||||
|
@ -72,7 +75,6 @@ namespace libtorrent
|
|||
, m_name_lookup(ios)
|
||||
, m_socket(ios, boost::bind(&udp_tracker_connection::on_receive, self(), _1, _2, _3, _4), cc)
|
||||
, m_transaction_id(0)
|
||||
, m_connection_id(0)
|
||||
, m_ses(ses)
|
||||
, m_attempts(0)
|
||||
, m_state(action_error)
|
||||
|
@ -185,16 +187,32 @@ namespace libtorrent
|
|||
|
||||
if (cb) cb->m_tracker_address = tcp::endpoint(m_target.address(), m_target.port());
|
||||
|
||||
if (bind_interface() != address_v4::any())
|
||||
error_code ec;
|
||||
m_socket.bind(udp::endpoint(bind_interface(), 0), ec);
|
||||
if (ec)
|
||||
{
|
||||
error_code ec;
|
||||
m_socket.bind(udp::endpoint(bind_interface(), 0), ec);
|
||||
if (ec)
|
||||
fail(-1, ec.message().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
std::map<address, connection_cache_entry>::iterator cc
|
||||
= m_connection_cache.find(m_target.address());
|
||||
if (cc != m_connection_cache.end())
|
||||
{
|
||||
// we found a cached entry! Now, we can only
|
||||
// use if if it hasn't expired
|
||||
if (time_now() < cc->second.expires)
|
||||
{
|
||||
fail(-1, ec.message().c_str());
|
||||
if (tracker_req().kind == tracker_request::announce_request)
|
||||
send_udp_announce();
|
||||
else if (tracker_req().kind == tracker_request::scrape_request)
|
||||
send_udp_scrape();
|
||||
return;
|
||||
}
|
||||
// if it expired, remove it from the cache
|
||||
m_connection_cache.erase(cc);
|
||||
}
|
||||
|
||||
send_udp_connect();
|
||||
}
|
||||
|
||||
|
@ -277,8 +295,8 @@ namespace libtorrent
|
|||
if (cb)
|
||||
{
|
||||
char msg[200];
|
||||
snprintf(msg, 200, "*** UDP_TRACKER_RESPONSE [ cid: %x%x ]"
|
||||
, int(m_connection_id >> 32), int(m_connection_id & 0xffffffff));
|
||||
snprintf(msg, 200, "*** UDP_TRACKER_RESPONSE [ tid: %x%x ]"
|
||||
, int(transaction >> 32), int(transaction & 0xffffffff));
|
||||
cb->debug_log(msg);
|
||||
}
|
||||
#endif
|
||||
|
@ -309,7 +327,10 @@ namespace libtorrent
|
|||
// reset transaction
|
||||
m_transaction_id = 0;
|
||||
m_attempts = 0;
|
||||
m_connection_id = detail::read_int64(buf);
|
||||
boost::uint64_t connection_id = detail::read_int64(buf);
|
||||
connection_cache_entry& cce = m_connection_cache[m_target.address()];
|
||||
cce.connection_id = connection_id;
|
||||
cce.expires = time_now() + seconds(m_ses.m_settings.udp_tracker_token_expiry);
|
||||
|
||||
if (tracker_req().kind == tracker_request::announce_request)
|
||||
send_udp_announce();
|
||||
|
@ -363,10 +384,16 @@ namespace libtorrent
|
|||
|
||||
if (!m_socket.is_open()) return; // the operation was aborted
|
||||
|
||||
std::map<address, connection_cache_entry>::iterator i
|
||||
= m_connection_cache.find(m_target.address());
|
||||
// this isn't really supposed to happen
|
||||
TORRENT_ASSERT(i != m_connection_cache.end());
|
||||
if (i == m_connection_cache.end()) return;
|
||||
|
||||
char buf[8 + 4 + 4 + 20];
|
||||
char* out = buf;
|
||||
|
||||
detail::write_int64(m_connection_id, out); // connection_id
|
||||
detail::write_int64(i->second.connection_id, out); // connection_id
|
||||
detail::write_int32(action_scrape, out); // action (scrape)
|
||||
detail::write_int32(m_transaction_id, out); // transaction_id
|
||||
// info_hash
|
||||
|
@ -390,8 +417,6 @@ namespace libtorrent
|
|||
{
|
||||
if (size < 20) return;
|
||||
|
||||
restart_read_timeout();
|
||||
|
||||
buf += 8; // skip header
|
||||
restart_read_timeout();
|
||||
int interval = detail::read_int32(buf);
|
||||
|
@ -517,7 +542,13 @@ namespace libtorrent
|
|||
const bool stats = req.send_stats;
|
||||
session_settings const& settings = m_ses.settings();
|
||||
|
||||
detail::write_int64(m_connection_id, out); // connection_id
|
||||
std::map<address, connection_cache_entry>::iterator i
|
||||
= m_connection_cache.find(m_target.address());
|
||||
// this isn't really supposed to happen
|
||||
TORRENT_ASSERT(i != m_connection_cache.end());
|
||||
if (i == m_connection_cache.end()) return;
|
||||
|
||||
detail::write_int64(i->second.connection_id, out); // connection_id
|
||||
detail::write_int32(action_announce, out); // action (announce)
|
||||
detail::write_int32(m_transaction_id, out); // transaction_id
|
||||
std::copy(req.info_hash.begin(), req.info_hash.end(), out); // info_hash
|
||||
|
|
Loading…
Reference in New Issue