added support for uTorrent interpretation of multi-tracker torrents (off by default)

This commit is contained in:
Arvid Norberg 2009-06-28 20:21:55 +00:00
parent 6ddf63197f
commit 8ee50045ca
6 changed files with 71 additions and 14 deletions

View File

@ -1,3 +1,4 @@
* added support for uTorrent interpretation of multi-tracker torrents
* handle torrents with duplicate filenames
* piece timeouts are adjusted to download rate limits
* encodes urls in torrent files that needs to be encoded

View File

@ -41,6 +41,7 @@ void bind_session_settings()
.def_readwrite("num_want", &session_settings::num_want)
.def_readwrite("initial_picker_threshold", &session_settings::initial_picker_threshold)
.def_readwrite("allowed_fast_set_size", &session_settings::allowed_fast_set_size)
.def_readwrite("max_queued_disk_bytes", &session_settings::max_queued_disk_bytes)
.def_readwrite("handshake_timeout", &session_settings::handshake_timeout)
#ifndef TORRENT_DISABLE_DHT
.def_readwrite("use_dht_as_fallback", &session_settings::use_dht_as_fallback)
@ -82,6 +83,7 @@ void bind_session_settings()
.def_readwrite("auto_manage_startup", &session_settings::auto_manage_startup)
.def_readwrite("rate_limit_ip_overhead", &session_settings::rate_limit_ip_overhead)
.def_readwrite("announce_to_all_trackers", &session_settings::announce_to_all_trackers)
.def_readwrite("announce_to_all_tiers", &session_settings::announce_to_all_tiers)
.def_readwrite("prefer_udp_trackers", &session_settings::prefer_udp_trackers)
.def_readwrite("strict_super_seeding", &session_settings::strict_super_seeding)
.def_readwrite("seeding_piece_quota", &session_settings::seeding_piece_quota)

View File

@ -3486,6 +3486,8 @@ session_settings
bool rate_limit_ip_overhead;
bool announce_to_all_trackers;
bool announce_to_all_tiers;
bool prefer_udp_trackers;
bool strict_super_seeding;
@ -3837,10 +3839,14 @@ drained from the rate limiters, to avoid exceeding the limits with the total tra
``announce_to_all_trackers`` controls how multi tracker torrents are
treated. If this is set to true, all trackers in the same tier are
announced to in parallel. If all trackers in tier 0 fails, all trackers
in tier 1 are announced as well. This is the uTorrent behavior. If it's
set to false, the behavior is as defined by the multi tracker
specification. It defaults to false, which is the same behavior previous
versions of libtorrent has had as well.
in tier 1 are announced as well. If it's set to false, the behavior is as
defined by the multi tracker specification. It defaults to false, which
is the same behavior previous versions of libtorrent has had as well.
``announce_to_all_tiers`` also controls how multi tracker torrents are
treated. When this is set to true, one tracker from each tier is announced
to. This is the uTorrent behavior. This is false by default in order
to comply with the multi-tracker specification.
``prefer_udp_trackers`` is true by default. It means that trackers may
be rearranged in a way that udp trackers are always tried before http

View File

@ -763,7 +763,8 @@ int main(int argc, char* argv[])
settings.user_agent = "client_test/" LIBTORRENT_VERSION;
settings.auto_upload_slots_rate_based = true;
settings.announce_to_all_trackers = true;
//settings.announce_to_all_tiers = true;
//settings.announce_to_all_trackers = true;
settings.optimize_hashing_for_speed = false;
settings.disk_cache_algorithm = session_settings::largest_contiguous;

View File

@ -154,6 +154,7 @@ namespace libtorrent
, auto_manage_startup(120)
, rate_limit_ip_overhead(true)
, announce_to_all_trackers(false)
, announce_to_all_tiers(false)
, prefer_udp_trackers(true)
, strict_super_seeding(false)
, seeding_piece_quota(3)
@ -526,10 +527,18 @@ namespace libtorrent
// the limits with the total traffic
bool rate_limit_ip_overhead;
// this announces to all trackers within the current
// tier. Trackers within a tier are supposed to share
// peers, this could be used for trackers that don't,
// and require the clients to announce to all of them.
bool announce_to_all_trackers;
// if set to true, multi tracker torrents are treated
// the same way uTorrent treats them. It defaults to
// false in order to comply with the extension definition.
bool announce_to_all_trackers;
// When this is enabled, one tracker from each tier is
// announced
bool announce_to_all_tiers;
// when this is set to true, if there is a tracker entry
// with udp:// protocol, it is preferred over the same

View File

@ -1157,15 +1157,35 @@ namespace libtorrent
ptime now = time_now();
// the tier is kept as INT_MAX until we find the first
// tracker that works, then it's set to that tracker's
// tier.
int tier = INT_MAX;
// have we sent an announce in this tier yet?
bool sent_announce = false;
for (int i = 0; i < int(m_trackers.size()); ++i)
{
announce_entry& ae = m_trackers[i];
if (ae.tier > tier) break;
if (ae.is_working()) tier = ae.tier;
if (m_settings.announce_to_all_tiers
&& sent_announce
&& ae.tier <= tier
&& tier != INT_MAX)
continue;
if (ae.tier > tier && !m_settings.announce_to_all_tiers) break;
if (ae.is_working()) { tier = ae.tier; sent_announce = false; }
if (!ae.can_announce(now))
{
if (ae.is_working() && !m_settings.announce_to_all_trackers) break;
if (ae.is_working())
{
sent_announce = true; // this counts
if (!m_settings.announce_to_all_trackers
&& !m_settings.announce_to_all_tiers)
break;
}
continue;
}
@ -1203,7 +1223,11 @@ namespace libtorrent
tracker_announce_alert(get_handle(), req.url, req.event));
}
if (ae.is_working() && !m_settings.announce_to_all_trackers) break;
sent_announce = true;
if (ae.is_working()
&& !m_settings.announce_to_all_trackers
&& !m_settings.announce_to_all_tiers)
break;
}
update_tracker_timer();
}
@ -4854,15 +4878,29 @@ namespace libtorrent
ptime next_announce = max_time();
int tier = INT_MAX;
bool found_working = false;
for (std::vector<announce_entry>::iterator i = m_trackers.begin()
, end(m_trackers.end()); i != end; ++i)
{
if (i->tier > tier) break;
if (i->is_working()) tier = i->tier;
if (m_settings.announce_to_all_tiers
&& found_working
&& i->tier <= tier
&& tier != INT_MAX)
continue;
if (i->tier > tier && !m_settings.announce_to_all_tiers) break;
if (i->is_working()) { tier = i->tier; found_working = false; }
if (i->fails >= i->fail_limit && i->fail_limit != 0) continue;
if (i->updating) continue;
if (i->updating) { found_working = true; continue; }
if (i->next_announce < next_announce) next_announce = i->next_announce;
if (i->is_working() && !m_settings.announce_to_all_trackers) break;
if (i->is_working())
{
found_working = true;
if (!m_settings.announce_to_all_trackers
&& !m_settings.announce_to_all_tiers) break;
}
}
if (next_announce == max_time()) return;