fix issue where the current tracker would be skipped for the next tracker in the same tier
This commit is contained in:
parent
82f87b0655
commit
02a01fa22e
|
@ -1490,10 +1490,10 @@ namespace libtorrent
|
||||||
// is is disabled while paused and checking files
|
// is is disabled while paused and checking files
|
||||||
bool m_announcing:1;
|
bool m_announcing:1;
|
||||||
|
|
||||||
// this is true while the tracker deadline timer
|
// this is > 0 while the tracker deadline timer
|
||||||
// is in use. i.e. one or more trackers are waiting
|
// is in use. i.e. one or more trackers are waiting
|
||||||
// for a reannounce
|
// for a reannounce
|
||||||
bool m_waiting_tracker:1;
|
boost::int8_t m_waiting_tracker;
|
||||||
|
|
||||||
// ----
|
// ----
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,9 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "test.hpp"
|
#include "test.hpp"
|
||||||
#include "settings.hpp"
|
#include "settings.hpp"
|
||||||
#include "setup_swarm.hpp"
|
#include "setup_swarm.hpp"
|
||||||
|
#include "setup_transfer.hpp" // for addr()
|
||||||
|
#include "utils.hpp" // for print_alerts
|
||||||
|
#include "create_torrent.hpp"
|
||||||
#include "simulator/simulator.hpp"
|
#include "simulator/simulator.hpp"
|
||||||
#include "simulator/http_server.hpp"
|
#include "simulator/http_server.hpp"
|
||||||
#include "simulator/utils.hpp"
|
#include "simulator/utils.hpp"
|
||||||
|
@ -52,6 +55,12 @@ using chrono::duration_cast;
|
||||||
// seconds
|
// seconds
|
||||||
const int duration = 10000;
|
const int duration = 10000;
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
boost::shared_ptr<T> clone_ptr(boost::shared_ptr<T> const& ptr)
|
||||||
|
{
|
||||||
|
return boost::make_shared<T>(*ptr);
|
||||||
|
}
|
||||||
|
|
||||||
void test_interval(int interval)
|
void test_interval(int interval)
|
||||||
{
|
{
|
||||||
using sim::asio::ip::address_v4;
|
using sim::asio::ip::address_v4;
|
||||||
|
@ -746,7 +755,7 @@ boost::shared_ptr<torrent_info> make_torrent(bool priv)
|
||||||
{
|
{
|
||||||
file_storage fs;
|
file_storage fs;
|
||||||
fs.add_file("foobar", 13241);
|
fs.add_file("foobar", 13241);
|
||||||
create_torrent ct(fs);
|
lt::create_torrent ct(fs);
|
||||||
|
|
||||||
ct.add_tracker("http://tracker.com:8080/announce");
|
ct.add_tracker("http://tracker.com:8080/announce");
|
||||||
|
|
||||||
|
@ -907,6 +916,112 @@ TORRENT_TEST(tracker_user_agent_privacy_mode_private_torrent)
|
||||||
TEST_EQUAL(got_announce, true);
|
TEST_EQUAL(got_announce, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This test sets up two peers, one seed an one downloader. The downloader has
|
||||||
|
// two trackers, both in tier 0. The behavior we expect is that it picks one of
|
||||||
|
// the trackers at random and announces to it. Since both trackers are working,
|
||||||
|
// it should not announce to the tracker it did not initially pick.
|
||||||
|
|
||||||
|
// #error parameterize this test over adding the trackers into different tiers
|
||||||
|
// and setting "announce_to_all_tiers"
|
||||||
|
|
||||||
|
TORRENT_TEST(tracker_tiers)
|
||||||
|
{
|
||||||
|
using namespace libtorrent;
|
||||||
|
|
||||||
|
char const* peer0_ip = "50.0.0.1";
|
||||||
|
char const* peer1_ip = "50.0.0.2";
|
||||||
|
|
||||||
|
using asio::ip::address;
|
||||||
|
address peer0 = addr(peer0_ip);
|
||||||
|
address peer1 = addr(peer1_ip);
|
||||||
|
|
||||||
|
// setup the simulation
|
||||||
|
sim::default_config network_cfg;
|
||||||
|
sim::simulation sim{network_cfg};
|
||||||
|
sim::asio::io_service ios0 { sim, peer0 };
|
||||||
|
sim::asio::io_service ios1 { sim, peer1 };
|
||||||
|
|
||||||
|
sim::asio::io_service tracker1(sim, address_v4::from_string("3.0.0.1"));
|
||||||
|
sim::asio::io_service tracker2(sim, address_v4::from_string("3.0.0.2"));
|
||||||
|
sim::http_server http1(tracker1, 8080);
|
||||||
|
sim::http_server http2(tracker2, 8080);
|
||||||
|
|
||||||
|
bool received_announce[2] = {false, false};
|
||||||
|
http1.register_handler("/announce"
|
||||||
|
, [&](std::string method, std::string req
|
||||||
|
, std::map<std::string, std::string>&)
|
||||||
|
{
|
||||||
|
received_announce[0] = true;
|
||||||
|
std::string ret = "d8:intervali60e5:peers0:e";
|
||||||
|
return sim::send_response(200, "OK", ret.size()) + ret;
|
||||||
|
});
|
||||||
|
|
||||||
|
http2.register_handler("/announce"
|
||||||
|
, [&](std::string method, std::string req
|
||||||
|
, std::map<std::string, std::string>&)
|
||||||
|
{
|
||||||
|
received_announce[1] = true;
|
||||||
|
std::string ret = "d8:intervali60e5:peers0:e";
|
||||||
|
return sim::send_response(200, "OK", ret.size()) + ret;
|
||||||
|
});
|
||||||
|
|
||||||
|
lt::session_proxy zombie[2];
|
||||||
|
|
||||||
|
// setup settings pack to use for the session (customization point)
|
||||||
|
lt::settings_pack pack = settings();
|
||||||
|
// create session
|
||||||
|
std::shared_ptr<lt::session> ses[2];
|
||||||
|
pack.set_str(settings_pack::listen_interfaces, peer0_ip + std::string(":6881"));
|
||||||
|
ses[0] = std::make_shared<lt::session>(pack, ios0);
|
||||||
|
|
||||||
|
pack.set_str(settings_pack::listen_interfaces, peer1_ip + std::string(":6881"));
|
||||||
|
ses[1] = std::make_shared<lt::session>(pack, ios1);
|
||||||
|
|
||||||
|
// only monitor alerts for session 0 (the downloader)
|
||||||
|
print_alerts(*ses[0], [=](lt::session& ses, lt::alert const* a) {
|
||||||
|
if (auto ta = alert_cast<lt::add_torrent_alert>(a))
|
||||||
|
{
|
||||||
|
ta->handle.connect_peer(lt::tcp::endpoint(peer1, 6881));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
print_alerts(*ses[1]);
|
||||||
|
|
||||||
|
// the first peer is a downloader, the second peer is a seed
|
||||||
|
lt::add_torrent_params params = ::create_torrent(1);
|
||||||
|
auto ti2 = clone_ptr(params.ti);
|
||||||
|
params.flags &= ~lt::add_torrent_params::flag_auto_managed;
|
||||||
|
params.flags &= ~lt::add_torrent_params::flag_paused;
|
||||||
|
|
||||||
|
// These trackers are in the same tier. libtorrent is expected to pick one at
|
||||||
|
// random and stick to it, never announce to the other one.
|
||||||
|
params.ti->add_tracker("http://3.0.0.1:8080/announce", 0);
|
||||||
|
params.ti->add_tracker("http://3.0.0.2:8080/announce", 0);
|
||||||
|
params.save_path = save_path(0);
|
||||||
|
ses[0]->async_add_torrent(params);
|
||||||
|
|
||||||
|
params.ti = ti2;
|
||||||
|
params.save_path = save_path(1);
|
||||||
|
ses[1]->async_add_torrent(params);
|
||||||
|
|
||||||
|
sim::timer t(sim, lt::minutes(30), [&](boost::system::error_code const& ec)
|
||||||
|
{
|
||||||
|
TEST_CHECK(received_announce[0] != received_announce[1]);
|
||||||
|
TEST_CHECK(ses[0]->get_torrents()[0].status().is_seeding);
|
||||||
|
TEST_CHECK(ses[1]->get_torrents()[0].status().is_seeding);
|
||||||
|
|
||||||
|
// shut down
|
||||||
|
int idx = 0;
|
||||||
|
for (auto& s : ses)
|
||||||
|
{
|
||||||
|
zombie[idx++] = s->abort();
|
||||||
|
s.reset();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
sim.run();
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: test external IP
|
// TODO: test external IP
|
||||||
// TODO: test with different queuing settings
|
// TODO: test with different queuing settings
|
||||||
// TODO: test when a torrent transitions from downloading to finished and
|
// TODO: test when a torrent transitions from downloading to finished and
|
||||||
|
|
|
@ -116,9 +116,10 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
// if we're a seed and we haven't sent a completed
|
// if we're a seed and we haven't sent a completed
|
||||||
// event, we need to let this announce through
|
// event, we need to let this announce through
|
||||||
bool need_send_complete = is_seed && !complete_sent;
|
bool const need_send_complete = is_seed && !complete_sent;
|
||||||
|
|
||||||
return now >= next_announce
|
// add some slack here for rounding errors
|
||||||
|
return now + seconds(1) >= next_announce
|
||||||
&& (now >= min_announce || need_send_complete)
|
&& (now >= min_announce || need_send_complete)
|
||||||
&& (fails < fail_limit || fail_limit == 0)
|
&& (fails < fail_limit || fail_limit == 0)
|
||||||
&& !updating;
|
&& !updating;
|
||||||
|
|
|
@ -247,7 +247,7 @@ namespace libtorrent
|
||||||
, m_files_checked(false)
|
, m_files_checked(false)
|
||||||
, m_storage_mode(p.storage_mode)
|
, m_storage_mode(p.storage_mode)
|
||||||
, m_announcing(false)
|
, m_announcing(false)
|
||||||
, m_waiting_tracker(false)
|
, m_waiting_tracker(0)
|
||||||
, m_active_time(0)
|
, m_active_time(0)
|
||||||
, m_last_working_tracker(-1)
|
, m_last_working_tracker(-1)
|
||||||
, m_finished_time(0)
|
, m_finished_time(0)
|
||||||
|
@ -2973,7 +2973,8 @@ namespace {
|
||||||
#endif
|
#endif
|
||||||
boost::shared_ptr<torrent> t = p.lock();
|
boost::shared_ptr<torrent> t = p.lock();
|
||||||
if (!t) return;
|
if (!t) return;
|
||||||
t->m_waiting_tracker = false;
|
TORRENT_ASSERT(t->m_waiting_tracker > 0);
|
||||||
|
--t->m_waiting_tracker;
|
||||||
|
|
||||||
if (e) return;
|
if (e) return;
|
||||||
t->on_tracker_announce();
|
t->on_tracker_announce();
|
||||||
|
@ -3224,7 +3225,7 @@ namespace {
|
||||||
req.num_want = (req.event == tracker_request::stopped)
|
req.num_want = (req.event == tracker_request::stopped)
|
||||||
? 0 : settings().get_int(settings_pack::num_want);
|
? 0 : settings().get_int(settings_pack::num_want);
|
||||||
|
|
||||||
time_point now = aux::time_now();
|
time_point const now = aux::time_now();
|
||||||
|
|
||||||
// the tier is kept as INT_MAX until we find the first
|
// the tier is kept as INT_MAX until we find the first
|
||||||
// tracker that works, then it's set to that tracker's
|
// tracker that works, then it's set to that tracker's
|
||||||
|
@ -10205,7 +10206,7 @@ namespace {
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
time_point next_tracker_announce = (std::max)(i->next_announce, i->min_announce);
|
time_point const next_tracker_announce = std::max(i->next_announce, i->min_announce);
|
||||||
if (next_tracker_announce < next_announce
|
if (next_tracker_announce < next_announce
|
||||||
&& (!found_working || i->is_working()))
|
&& (!found_working || i->is_working()))
|
||||||
next_announce = next_tracker_announce;
|
next_announce = next_tracker_announce;
|
||||||
|
@ -10229,7 +10230,7 @@ namespace {
|
||||||
// if m_waiting_tracker is false, expires_at() is undefined
|
// if m_waiting_tracker is false, expires_at() is undefined
|
||||||
if (m_waiting_tracker && m_tracker_timer.expires_at() == next_announce) return;
|
if (m_waiting_tracker && m_tracker_timer.expires_at() == next_announce) return;
|
||||||
|
|
||||||
m_waiting_tracker = true;
|
++m_waiting_tracker;
|
||||||
error_code ec;
|
error_code ec;
|
||||||
boost::weak_ptr<torrent> self(shared_from_this());
|
boost::weak_ptr<torrent> self(shared_from_this());
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue