restore the ipv6 http tracker argument, but restricted to only private torrents

This commit is contained in:
arvidn 2016-04-07 00:06:04 -04:00
parent f299d1578c
commit 876cef0d4c
4 changed files with 142 additions and 15 deletions

View File

@ -150,6 +150,9 @@ namespace libtorrent
boost::uint32_t key;
int num_want;
#if TORRENT_USE_IPV6
address_v6 ipv6;
#endif
sha1_hash info_hash;
peer_id pid;
address bind_ip;

View File

@ -39,6 +39,9 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/alert_types.hpp"
#include "libtorrent/announce_entry.hpp"
#include "libtorrent/session.hpp"
#include "libtorrent/create_torrent.hpp"
#include "libtorrent/file_storage.hpp"
#include "libtorrent/torrent_info.hpp"
using namespace libtorrent;
using namespace sim;
@ -397,7 +400,7 @@ void tracker_test(Setup setup, Announce a, Test1 test1, Test2 test2
p.name = "test-torrent";
p.save_path = ".";
p.info_hash.assign("abababababababababab");
int const delay = setup(p);
int const delay = setup(p, *ses);
ses->async_add_torrent(p);
// run the test 5 seconds in
@ -434,7 +437,7 @@ void tracker_test(Setup setup, Announce a, Test1 test1, Test2 test2
template <typename Announce, typename Test1, typename Test2>
void tracker_test(Announce a, Test1 test1, Test2 test2, char const* url_path = "/announce")
{
tracker_test([](lt::add_torrent_params& p) {
tracker_test([](lt::add_torrent_params& p, lt::session&) {
p.trackers.push_back("http://tracker.com:8080/announce");
return 5;
},
@ -629,7 +632,7 @@ TORRENT_TEST(try_next)
bool got_announce = false;
tracker_test(
[](lt::add_torrent_params& p)
[](lt::add_torrent_params& p, lt::session&)
{
// TODO: 3 use tracker_tiers here to put the trackers in different tiers
p.trackers.push_back("udp://failing-tracker.com/announce");
@ -691,6 +694,113 @@ TORRENT_TEST(try_next)
TEST_EQUAL(got_announce, true);
}
boost::shared_ptr<torrent_info> make_torrent(bool priv)
{
file_storage fs;
fs.add_file("foobar", 13241);
create_torrent ct(fs);
ct.add_tracker("http://tracker.com:8080/announce");
for (int i = 0; i < ct.num_pieces(); ++i)
ct.set_hash(i, sha1_hash(0));
ct.set_priv(priv);
entry e = ct.generate();
std::vector<char> buf;
bencode(std::back_inserter(buf), e);
error_code ec;
return boost::make_shared<torrent_info>(buf.data(), buf.size(), ec);
}
// make sure we _do_ send our IPv6 address to trackers for private torrents
TORRENT_TEST(tracker_ipv6_argument)
{
bool got_announce = false;
bool got_ipv6 = false;
tracker_test(
[](lt::add_torrent_params& p, lt::session& ses)
{
settings_pack pack;
pack.set_bool(settings_pack::anonymous_mode, false);
ses.apply_settings(pack);
p.ti = make_torrent(true);
return 60;
},
[&](std::string method, std::string req
, std::map<std::string, std::string>& headers)
{
got_announce = true;
int pos = req.find("&ipv6=");
TEST_CHECK(pos != std::string::npos);
got_ipv6 = pos != std::string::npos;
return sim::send_response(200, "OK", 11) + "d5:peers0:e";
}
, [](torrent_handle h) {}
, [](torrent_handle h) {});
TEST_EQUAL(got_announce, true);
TEST_EQUAL(got_ipv6, true);
}
// make sure we do _not_ send our IPv6 address to trackers for non-private
// torrents
TORRENT_TEST(tracker_ipv6_argument_non_private)
{
bool got_announce = false;
bool got_ipv6 = false;
tracker_test(
[](lt::add_torrent_params& p, lt::session& ses)
{
settings_pack pack;
pack.set_bool(settings_pack::anonymous_mode, false);
ses.apply_settings(pack);
p.ti = make_torrent(false);
return 60;
},
[&](std::string method, std::string req
, std::map<std::string, std::string>& headers)
{
got_announce = true;
int pos = req.find("&ipv6=");
TEST_CHECK(pos == std::string::npos);
got_ipv6 = pos != std::string::npos;
return sim::send_response(200, "OK", 11) + "d5:peers0:e";
}
, [](torrent_handle h) {}
, [](torrent_handle h) {});
TEST_EQUAL(got_announce, true);
TEST_EQUAL(got_ipv6, false);
}
TORRENT_TEST(tracker_ipv6_argument_privacy_mode)
{
bool got_announce = false;
bool got_ipv6 = false;
tracker_test(
[](lt::add_torrent_params& p, lt::session& ses)
{
settings_pack pack;
pack.set_bool(settings_pack::anonymous_mode, true);
ses.apply_settings(pack);
p.ti = make_torrent(true);
return 60;
},
[&](std::string method, std::string req
, std::map<std::string, std::string>& headers)
{
got_announce = true;
int pos = req.find("&ipv6=");
TEST_CHECK(pos == std::string::npos);
got_ipv6 = pos != std::string::npos;
return sim::send_response(200, "OK", 11) + "d5:peers0:e";
}
, [](torrent_handle h) {}
, [](torrent_handle h) {});
TEST_EQUAL(got_announce, true);
TEST_EQUAL(got_ipv6, false);
}
// TODO: test external IP
// TODO: test with different queuing settings
// TODO: test when a torrent transitions from downloading to finished and

View File

@ -183,20 +183,22 @@ namespace libtorrent
{
url += "&ip=" + escape_string(announce_ip.c_str(), announce_ip.size());
}
// TODO: support this somehow
/* else if (settings.get_bool(settings_pack::announce_double_nat)
&& is_local(m_ses.listen_address()))
{
// only use the global external listen address here
// if it turned out to be on a local network
// since otherwise the tracker should use our
// source IP to determine our origin
url += "&ip=" + print_address(m_ses.listen_address());
}
*/
}
}
#if TORRENT_USE_IPV6
if (tracker_req().ipv6 != address_v6() && !i2p)
{
error_code err;
std::string const ip = tracker_req().ipv6.to_string(err);
if (!err)
{
url += "&ipv6=";
url += ip;
}
}
#endif
m_tracker_connection.reset(new http_connection(get_io_service(), m_man.host_resolver()
, boost::bind(&http_tracker_connection::on_response, shared_from_this(), _1, _2, _3, _4)
, true, settings.get_int(settings_pack::max_http_recv_buffer_size)

View File

@ -3140,7 +3140,19 @@ namespace libtorrent
if (req.downloaded < 0) req.downloaded = 0;
req.event = e;
error_code ec;
#if TORRENT_USE_IPV6
// since sending our IPv6 address to the tracker may be sensitive. Only
// do that if we're not in anonymous mode and if it's a private torrent
if (!settings().get_bool(settings_pack::anonymous_mode)
&& m_torrent_file
&& m_torrent_file->priv())
{
tcp::endpoint ep;
ep = m_ses.get_ipv6_interface();
if (ep != tcp::endpoint()) req.ipv6 = ep.address().to_v6();
}
#endif
// if we are aborting. we don't want any new peers
req.num_want = (req.event == tracker_request::stopped)