From 0d8a5a8a444a402c0627aa10212bfed7dea791f1 Mon Sep 17 00:00:00 2001 From: arvidn Date: Mon, 19 Nov 2018 01:56:30 +0100 Subject: [PATCH] add support for &ipv4= tracker argument --- ChangeLog | 1 + include/libtorrent/tracker_manager.hpp | 1 + simulation/test_tracker.cpp | 25 ++++++++++++++++++------- src/http_tracker_connection.cpp | 11 +++++++++++ src/torrent.cpp | 12 +++++++----- 5 files changed, 38 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 33ff51dd7..b464801fe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,6 @@ 1.2 release + * support &ipv4= tracker argument for private torrents * renamed debug_notification to connect_notification * when updating listen sockets, only post alerts for new ones * deprecate anonymous_mode_alert diff --git a/include/libtorrent/tracker_manager.hpp b/include/libtorrent/tracker_manager.hpp index 0b5a0f6be..86331adbc 100644 --- a/include/libtorrent/tracker_manager.hpp +++ b/include/libtorrent/tracker_manager.hpp @@ -144,6 +144,7 @@ namespace libtorrent { std::uint32_t key; int num_want; std::vector ipv6; + std::vector ipv4; sha1_hash info_hash; peer_id pid; diff --git a/simulation/test_tracker.cpp b/simulation/test_tracker.cpp index f83329bd9..9907422d5 100644 --- a/simulation/test_tracker.cpp +++ b/simulation/test_tracker.cpp @@ -970,11 +970,13 @@ TORRENT_TEST(tracker_ipv6_argument) { bool got_announce = false; bool got_ipv6 = false; + bool got_ipv4 = false; tracker_test( [](lt::add_torrent_params& p, lt::session& ses) { settings_pack pack; pack.set_bool(settings_pack::anonymous_mode, false); + pack.set_str(settings_pack::listen_interfaces, "10.0.0.3:0,[ffff::1337]:0"); ses.apply_settings(pack); p.ti = make_torrent(true); return 60; @@ -984,13 +986,22 @@ TORRENT_TEST(tracker_ipv6_argument) { got_announce = true; bool const stop_event = req.find("&event=stopped") != std::string::npos; - // stop events don't need to advertise the IPv6 address - std::string::size_type pos = req.find("&ipv6="); - TEST_CHECK(pos != std::string::npos || stop_event); - got_ipv6 |= pos != std::string::npos; - // make sure the IPv6 argument is url encoded - TEST_CHECK(req.substr(pos + 6, req.substr(pos + 6).find_first_of('&')) - == "ffff%3a%3a1337"); + // stop events don't need to advertise the IPv6/IPv4 address + { + std::string::size_type const pos = req.find("&ipv6="); + TEST_CHECK(pos != std::string::npos || stop_event); + got_ipv6 |= pos != std::string::npos; + // make sure the IPv6 argument is url encoded + TEST_EQUAL(req.substr(pos + 6, req.substr(pos + 6).find_first_of('&')) + , "ffff%3a%3a1337"); + } + + { + std::string::size_type const pos = req.find("&ipv4="); + TEST_CHECK(pos != std::string::npos || stop_event); + got_ipv4 |= pos != std::string::npos; + TEST_EQUAL(req.substr(pos + 6, req.substr(pos + 6).find_first_of('&')), "10.0.0.3"); + } return sim::send_response(200, "OK", 11) + "d5:peers0:e"; } , [](torrent_handle) {} diff --git a/src/http_tracker_connection.cpp b/src/http_tracker_connection.cpp index 3f527e813..f1d1e934e 100644 --- a/src/http_tracker_connection.cpp +++ b/src/http_tracker_connection.cpp @@ -172,6 +172,17 @@ namespace libtorrent { } } + if (!tracker_req().ipv4.empty() && !i2p) + { + for (auto const& v4 : tracker_req().ipv4) + { + error_code err; + std::string const ip = v4.to_string(err); + if (err) continue; + url += "&ipv4="; + url += escape_string(ip); + } + } if (!tracker_req().ipv6.empty() && !i2p) { for (auto const& v6 : tracker_req().ipv6) diff --git a/src/torrent.cpp b/src/torrent.cpp index b50df9d9c..ca216a0fc 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -2782,11 +2782,13 @@ bool is_downloading_state(int const st) { m_ses.for_each_listen_socket([&](aux::listen_socket_handle const& s) { - if (s.is_ssl() != is_ssl_torrent()) - return; - if (!is_v6(s.get_local_endpoint())) - return; - req.ipv6.push_back(s.get_local_endpoint().address().to_v6()); + if (s.is_ssl() != is_ssl_torrent()) return; + tcp::endpoint const ep = s.get_local_endpoint(); + if (is_any(ep.address())) return; + if (is_v6(ep)) + req.ipv6.push_back(ep.address().to_v6()); + else + req.ipv4.push_back(ep.address().to_v4()); }); }