fix IPv6 tracker support by performing the second announce in more cases
This commit is contained in:
parent
73e898e38e
commit
fe37884bc6
|
@ -1,3 +1,4 @@
|
||||||
|
* fix IPv6 tracker support by performing the second announce in more cases
|
||||||
* fix utf-8 encoding check in torrent parser
|
* fix utf-8 encoding check in torrent parser
|
||||||
* fix infinite loop when parsing maliciously crafted torrents
|
* fix infinite loop when parsing maliciously crafted torrents
|
||||||
* fix invalid read in parse_int in bdecoder
|
* fix invalid read in parse_int in bdecoder
|
||||||
|
|
|
@ -101,6 +101,7 @@ namespace libtorrent
|
||||||
, send_stats(true)
|
, send_stats(true)
|
||||||
, private_torrent(false)
|
, private_torrent(false)
|
||||||
, triggered_manually(false)
|
, triggered_manually(false)
|
||||||
|
, second_announce(false)
|
||||||
#ifdef TORRENT_USE_OPENSSL
|
#ifdef TORRENT_USE_OPENSSL
|
||||||
, ssl_ctx(0)
|
, ssl_ctx(0)
|
||||||
#endif
|
#endif
|
||||||
|
@ -168,6 +169,11 @@ namespace libtorrent
|
||||||
// scrape_tracker() or force_reannounce()
|
// scrape_tracker() or force_reannounce()
|
||||||
bool triggered_manually;
|
bool triggered_manually;
|
||||||
|
|
||||||
|
// this is set when announcing to the next address family. There are only
|
||||||
|
// two address families now, so when this is set, we won't trigger another
|
||||||
|
// automatic announce
|
||||||
|
bool second_announce;
|
||||||
|
|
||||||
#ifdef TORRENT_USE_OPENSSL
|
#ifdef TORRENT_USE_OPENSSL
|
||||||
boost::asio::ssl::context* ssl_ctx;
|
boost::asio::ssl::context* ssl_ctx;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -287,9 +287,8 @@ void on_alert_notify(lt::session* ses)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// this test makes sure that a tracker whose host name resolves to both IPv6 and
|
void test_ipv6_support(char const* listen_interfaces
|
||||||
// IPv4 addresses will be announced to twice, once for each address family
|
, int const expect_v4, int const expect_v6)
|
||||||
TORRENT_TEST(ipv6_support)
|
|
||||||
{
|
{
|
||||||
using sim::asio::ip::address_v4;
|
using sim::asio::ip::address_v4;
|
||||||
sim_config network_cfg;
|
sim_config network_cfg;
|
||||||
|
@ -335,6 +334,7 @@ TORRENT_TEST(ipv6_support)
|
||||||
asio::io_service ios(sim, { address_v4::from_string("10.0.0.3")
|
asio::io_service ios(sim, { address_v4::from_string("10.0.0.3")
|
||||||
, address_v6::from_string("ffff::1337") });
|
, address_v6::from_string("ffff::1337") });
|
||||||
lt::settings_pack sett = settings();
|
lt::settings_pack sett = settings();
|
||||||
|
sett.set_str(settings_pack::listen_interfaces, listen_interfaces);
|
||||||
std::unique_ptr<lt::session> ses(new lt::session(sett, ios));
|
std::unique_ptr<lt::session> ses(new lt::session(sett, ios));
|
||||||
|
|
||||||
ses->set_alert_notify(std::bind(&on_alert_notify, ses.get()));
|
ses->set_alert_notify(std::bind(&on_alert_notify, ses.get()));
|
||||||
|
@ -370,9 +370,46 @@ TORRENT_TEST(ipv6_support)
|
||||||
sim.run();
|
sim.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_EQUAL(v4_announces, expect_v4);
|
||||||
|
TEST_EQUAL(v6_announces, expect_v6);
|
||||||
|
}
|
||||||
|
|
||||||
|
// this test makes sure that a tracker whose host name resolves to both IPv6 and
|
||||||
|
// IPv4 addresses will be announced to twice, once for each address family
|
||||||
|
TORRENT_TEST(ipv6_support)
|
||||||
|
{
|
||||||
// 2 because there's one announce on startup and one when shutting down
|
// 2 because there's one announce on startup and one when shutting down
|
||||||
TEST_EQUAL(v4_announces, 2);
|
test_ipv6_support("0.0.0.0:6881", 2, 2);
|
||||||
TEST_EQUAL(v6_announces, 2);
|
}
|
||||||
|
|
||||||
|
TORRENT_TEST(ipv6_support_bind_v4_v6_any)
|
||||||
|
{
|
||||||
|
test_ipv6_support("0.0.0.0:6881,[::0]:6881", 2, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
TORRENT_TEST(ipv6_support_bind_v6_any)
|
||||||
|
{
|
||||||
|
test_ipv6_support("[::0]:6881", 0, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
TORRENT_TEST(ipv6_support_bind_v4)
|
||||||
|
{
|
||||||
|
test_ipv6_support("10.0.0.3:6881", 2, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TORRENT_TEST(ipv6_support_bind_v6)
|
||||||
|
{
|
||||||
|
test_ipv6_support("[ffff::1337]:6881", 0, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
TORRENT_TEST(ipv6_support_bind_v4_v6)
|
||||||
|
{
|
||||||
|
test_ipv6_support("10.0.0.3:6881,[ffff::1337]:6881", 2, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
TORRENT_TEST(ipv6_support_bind_v6_v4)
|
||||||
|
{
|
||||||
|
test_ipv6_support("[ffff::1337]:6881,10.0.0.3:6881", 2, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// this runs a simulation of a torrent with tracker(s), making sure the request
|
// this runs a simulation of a torrent with tracker(s), making sure the request
|
||||||
|
|
|
@ -3641,15 +3641,12 @@ namespace {
|
||||||
// when talking to the tracker. If there is a matching interface
|
// when talking to the tracker. If there is a matching interface
|
||||||
// type in the tracker IP list, make another tracker request
|
// type in the tracker IP list, make another tracker request
|
||||||
// using that interface
|
// using that interface
|
||||||
// in order to avoid triggering this case over and over, don't
|
// in order to avoid triggering this case over and over, check whether
|
||||||
// do it if the bind IP for the tracker request that just completed
|
// this announce was itself triggered by this logic (second_announce)
|
||||||
// matches one of the listen interfaces, since that means this
|
|
||||||
// announce was the second one
|
|
||||||
|
|
||||||
if (((!is_any(m_ses.get_ipv6_interface().address()) && tracker_ip.is_v4())
|
if (((!is_any(m_ses.get_ipv6_interface().address()) && tracker_ip.is_v4())
|
||||||
|| (!is_any(m_ses.get_ipv4_interface().address()) && tracker_ip.is_v6()))
|
|| (!is_any(m_ses.get_ipv4_interface().address()) && tracker_ip.is_v6()))
|
||||||
&& r.bind_ip != m_ses.get_ipv4_interface().address()
|
&& !r.second_announce)
|
||||||
&& r.bind_ip != m_ses.get_ipv6_interface().address())
|
|
||||||
{
|
{
|
||||||
std::list<address>::const_iterator i = std::find_if(tracker_ips.begin()
|
std::list<address>::const_iterator i = std::find_if(tracker_ips.begin()
|
||||||
, tracker_ips.end(), boost::bind(&address::is_v4, _1) != tracker_ip.is_v4());
|
, tracker_ips.end(), boost::bind(&address::is_v4, _1) != tracker_ip.is_v4());
|
||||||
|
@ -3667,6 +3664,7 @@ namespace {
|
||||||
tracker_request req = r;
|
tracker_request req = r;
|
||||||
|
|
||||||
req.private_torrent = m_torrent_file->priv();
|
req.private_torrent = m_torrent_file->priv();
|
||||||
|
req.second_announce = true;
|
||||||
|
|
||||||
// tell the tracker to bind to the opposite protocol type
|
// tell the tracker to bind to the opposite protocol type
|
||||||
req.bind_ip = tracker_ip.is_v4()
|
req.bind_ip = tracker_ip.is_v4()
|
||||||
|
|
Loading…
Reference in New Issue