expand IPv4 in expand_unspecified_address

This commit is contained in:
arvidn 2020-01-09 15:41:47 +01:00 committed by Arvid Norberg
parent 0961427b50
commit 88d9c05e3c
7 changed files with 42 additions and 26 deletions

View File

@ -542,7 +542,7 @@ void test_udpv6_support(char const* listen_interfaces
TORRENT_TEST(ipv6_support) TORRENT_TEST(ipv6_support)
{ {
// null means default // null means default
test_ipv6_support(nullptr, 2, num_interfaces * 2); test_ipv6_support(nullptr, num_interfaces * 2, num_interfaces * 2);
} }
TORRENT_TEST(announce_no_listen) TORRENT_TEST(announce_no_listen)
@ -563,7 +563,7 @@ TORRENT_TEST(ipv6_support_bind_v4_v6_any)
{ {
// 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
// IPv6 will send announces for each interface // IPv6 will send announces for each interface
test_ipv6_support("0.0.0.0:6881,[::0]:6881", 2, num_interfaces * 2); test_ipv6_support("0.0.0.0:6881,[::0]:6881", num_interfaces * 2, num_interfaces * 2);
} }
TORRENT_TEST(ipv6_support_bind_v6_any) TORRENT_TEST(ipv6_support_bind_v6_any)

View File

@ -238,27 +238,24 @@ namespace aux {
} }
// To comply with BEP 45 multi homed clients must run separate DHT nodes // To comply with BEP 45 multi homed clients must run separate DHT nodes
// on each interface they use to talk to the DHT. For IPv6 this is enforced // on each interface they use to talk to the DHT. This is enforced
// by prohibiting creating a listen socket on [::]. Instead the list of // by prohibiting creating a listen socket on [::] and 0.0.0.0. Instead the list of
// interfaces is enumerated and sockets are created for each of them. // interfaces is enumerated and sockets are created for each of them.
// This is not enforced for 0.0.0.0 because multi homed IPv4 configurations
// are much less common and the presence of NAT means that we cannot
// automatically determine which interfaces should have DHT nodes started on
// them.
void expand_unspecified_address(span<ip_interface const> const ifs void expand_unspecified_address(span<ip_interface const> const ifs
, std::vector<listen_endpoint_t>& eps) , std::vector<listen_endpoint_t>& eps)
{ {
auto unspecified_begin = std::partition(eps.begin(), eps.end() auto unspecified_begin = std::partition(eps.begin(), eps.end()
, [](listen_endpoint_t const& ep) { return !(ep.addr.is_v6() && ep.addr.is_unspecified()); }); , [](listen_endpoint_t const& ep) { return !ep.addr.is_unspecified(); });
std::vector<listen_endpoint_t> unspecified_eps(unspecified_begin, eps.end()); std::vector<listen_endpoint_t> unspecified_eps(unspecified_begin, eps.end());
eps.erase(unspecified_begin, eps.end()); eps.erase(unspecified_begin, eps.end());
for (auto const& uep : unspecified_eps) for (auto const& uep : unspecified_eps)
{ {
bool const v4 = uep.addr.is_v4();
for (auto const& ipface : ifs) for (auto const& ipface : ifs)
{ {
if (!ipface.preferred) if (!ipface.preferred)
continue; continue;
if (ipface.interface_address.is_v4()) if (ipface.interface_address.is_v4() != v4)
continue; continue;
if (!uep.device.empty() && uep.device != ipface.name) if (!uep.device.empty() && uep.device != ipface.name)
continue; continue;
@ -4943,7 +4940,7 @@ namespace aux {
} }
} }
if (!match && !with_gateways.empty()) if (!match && !with_gateways.empty())
match = with_gateways[random(with_gateways.size() - 1)]; match = with_gateways[random(std::uint32_t(with_gateways.size() - 1))];
if (match) if (match)
{ {

View File

@ -306,6 +306,12 @@ TORRENT_TEST(expand_unspecified)
auto v4_nossl = ep("0.0.0.0", 6881); auto v4_nossl = ep("0.0.0.0", 6881);
auto v4_ssl = ep("0.0.0.0", 6882, tp::ssl); auto v4_ssl = ep("0.0.0.0", 6882, tp::ssl);
auto v4_loopb_nossl= ep("127.0.0.1", 6881);
auto v4_loopb_ssl = ep("127.0.0.1", 6882, tp::ssl);
auto v4_g1_nossl = ep("192.168.1.2", 6881);
auto v4_g1_ssl = ep("192.168.1.2", 6882, tp::ssl);
auto v4_g2_nossl = ep("24.172.48.90", 6881);
auto v4_g2_ssl = ep("24.172.48.90", 6882, tp::ssl);
auto v6_unsp_nossl = ep("::", 6883); auto v6_unsp_nossl = ep("::", 6883);
auto v6_unsp_ssl = ep("::", 6884, tp::ssl); auto v6_unsp_ssl = ep("::", 6884, tp::ssl);
auto v6_ll_nossl = ep("fe80::d250:99ff:fe0c:9b74", 6883); auto v6_ll_nossl = ep("fe80::d250:99ff:fe0c:9b74", 6883);
@ -321,17 +327,23 @@ TORRENT_TEST(expand_unspecified)
aux::expand_unspecified_address(ifs, eps); aux::expand_unspecified_address(ifs, eps);
TEST_EQUAL(eps.size(), 8); TEST_EQUAL(eps.size(), 12);
TEST_CHECK(std::count(eps.begin(), eps.end(), v4_nossl) == 1); TEST_CHECK(std::count(eps.begin(), eps.end(), v4_g1_nossl) == 1);
TEST_CHECK(std::count(eps.begin(), eps.end(), v4_ssl) == 1); TEST_CHECK(std::count(eps.begin(), eps.end(), v4_g1_ssl) == 1);
TEST_CHECK(std::count(eps.begin(), eps.end(), v4_g2_nossl) == 1);
TEST_CHECK(std::count(eps.begin(), eps.end(), v4_g2_ssl) == 1);
TEST_CHECK(std::count(eps.begin(), eps.end(), v6_ll_nossl) == 1); TEST_CHECK(std::count(eps.begin(), eps.end(), v6_ll_nossl) == 1);
TEST_CHECK(std::count(eps.begin(), eps.end(), v6_ll_ssl) == 1); TEST_CHECK(std::count(eps.begin(), eps.end(), v6_ll_ssl) == 1);
TEST_CHECK(std::count(eps.begin(), eps.end(), v6_g_nossl) == 1); TEST_CHECK(std::count(eps.begin(), eps.end(), v6_g_nossl) == 1);
TEST_CHECK(std::count(eps.begin(), eps.end(), v6_g_ssl) == 1); TEST_CHECK(std::count(eps.begin(), eps.end(), v6_g_ssl) == 1);
TEST_CHECK(std::count(eps.begin(), eps.end(), v6_loopb_ssl) == 1); TEST_CHECK(std::count(eps.begin(), eps.end(), v6_loopb_ssl) == 1);
TEST_CHECK(std::count(eps.begin(), eps.end(), v6_loopb_nossl) == 1); TEST_CHECK(std::count(eps.begin(), eps.end(), v6_loopb_nossl) == 1);
TEST_CHECK(std::count(eps.begin(), eps.end(), v4_loopb_ssl) == 1);
TEST_CHECK(std::count(eps.begin(), eps.end(), v4_loopb_nossl) == 1);
TEST_CHECK(std::count(eps.begin(), eps.end(), v6_unsp_nossl) == 0); TEST_CHECK(std::count(eps.begin(), eps.end(), v6_unsp_nossl) == 0);
TEST_CHECK(std::count(eps.begin(), eps.end(), v6_unsp_ssl) == 0); TEST_CHECK(std::count(eps.begin(), eps.end(), v6_unsp_ssl) == 0);
TEST_CHECK(std::count(eps.begin(), eps.end(), v4_nossl) == 0);
TEST_CHECK(std::count(eps.begin(), eps.end(), v4_ssl) == 0);
// test that a user configured endpoint is not duplicated // test that a user configured endpoint is not duplicated
auto v6_g_nossl_dev = ep("2601:646:c600:a3:d250:99ff:fe0c:9b74", 6883, "eth0"); auto v6_g_nossl_dev = ep("2601:646:c600:a3:d250:99ff:fe0c:9b74", 6883, "eth0");

View File

@ -541,18 +541,19 @@ TORRENT_TEST(reopen_network_sockets)
settings_pack p = settings(); settings_pack p = settings();
p.set_int(settings_pack::alert_mask, alert::all_categories); p.set_int(settings_pack::alert_mask, alert::all_categories);
p.set_str(settings_pack::listen_interfaces, "0.0.0.0:6881"); p.set_str(settings_pack::listen_interfaces, "127.0.0.1:6881");
p.set_bool(settings_pack::enable_upnp, true); p.set_bool(settings_pack::enable_upnp, true);
p.set_bool(settings_pack::enable_natpmp, true); p.set_bool(settings_pack::enable_natpmp, true);
lt::session s(p); lt::session s(p);
TEST_CHECK(count_alerts(s, 2, 4)); // NAT-PMP will be disabled when we only listen on loopback
TEST_CHECK(count_alerts(s, 2, 2));
s.reopen_network_sockets(session_handle::reopen_map_ports); s.reopen_network_sockets(session_handle::reopen_map_ports);
TEST_CHECK(count_alerts(s, 0, 4)); TEST_CHECK(count_alerts(s, 0, 2));
s.reopen_network_sockets({}); s.reopen_network_sockets({});

View File

@ -46,6 +46,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/announce_entry.hpp" #include "libtorrent/announce_entry.hpp"
#include "libtorrent/torrent.hpp" #include "libtorrent/torrent.hpp"
#include "libtorrent/aux_/path.hpp" #include "libtorrent/aux_/path.hpp"
#include "libtorrent/socket_io.hpp"
#include <fstream> #include <fstream>
@ -396,6 +397,9 @@ void test_udp_tracker(std::string const& iface, address tracker, tcp::endpoint c
std::this_thread::sleep_for(lt::milliseconds(100)); std::this_thread::sleep_for(lt::milliseconds(100));
} }
std::printf("peer_ep: %s expected: %s\n"
, lt::print_endpoint(peer_ep).c_str()
, lt::print_endpoint(expected_peer).c_str());
TEST_CHECK(peer_ep == expected_peer); TEST_CHECK(peer_ep == expected_peer);
std::printf("destructing session\n"); std::printf("destructing session\n");
@ -412,7 +416,11 @@ void test_udp_tracker(std::string const& iface, address tracker, tcp::endpoint c
TORRENT_TEST(udp_tracker_v4) TORRENT_TEST(udp_tracker_v4)
{ {
test_udp_tracker("127.0.0.1", address_v4::any(), ep("1.3.3.7", 1337)); // if the machine running the test doesn't have an actual IPv4 connection
// the test would fail with any other address than loopback (because it
// would be unreachable). This is true for some CI's, running containers
// without an internet connection
test_udp_tracker("127.0.0.1", address_v4::any(), ep("127.0.0.2", 1337));
} }
TORRENT_TEST(udp_tracker_v6) TORRENT_TEST(udp_tracker_v6)
@ -667,7 +675,7 @@ void test_stop_tracker_timeout(int const timeout)
settings_pack p = settings(); settings_pack p = settings();
p.set_bool(settings_pack::announce_to_all_trackers, true); p.set_bool(settings_pack::announce_to_all_trackers, true);
p.set_bool(settings_pack::announce_to_all_tiers, true); p.set_bool(settings_pack::announce_to_all_tiers, true);
p.set_str(settings_pack::listen_interfaces, "0.0.0.0:6881"); p.set_str(settings_pack::listen_interfaces, "127.0.0.1:6881");
p.set_int(settings_pack::stop_tracker_timeout, timeout); p.set_int(settings_pack::stop_tracker_timeout, timeout);
lt::session s(p); lt::session s(p);

View File

@ -146,10 +146,10 @@ struct udp_tracker
} }
else else
{ {
detail::write_uint8(1, ptr); detail::write_uint8(127, ptr);
detail::write_uint8(3, ptr); detail::write_uint8(0, ptr);
detail::write_uint8(3, ptr); detail::write_uint8(0, ptr);
detail::write_uint8(7, ptr); detail::write_uint8(2, ptr);
detail::write_uint16(1337, ptr); detail::write_uint16(1337, ptr);
} }
m_socket.send_to(boost::asio::buffer(buffer m_socket.send_to(boost::asio::buffer(buffer

View File

@ -42,7 +42,7 @@ class http_handler(BaseHTTPRequestHandler):
def do_GET(s): def do_GET(s):
print('INCOMING-REQUEST: ', s.requestline) print('INCOMING-REQUEST [from: {}]: {}'.format(s.request.getsockname(), s.requestline))
print(s.headers) print(s.headers)
sys.stdout.flush() sys.stdout.flush()
@ -55,8 +55,6 @@ class http_handler(BaseHTTPRequestHandler):
s.path = s.path[s.path.find('/'):] s.path = s.path[s.path.find('/'):]
file_path = os.path.normpath(s.path) file_path = os.path.normpath(s.path)
print(file_path)
print(s.path)
sys.stdout.flush() sys.stdout.flush()
if s.path == '/password_protected': if s.path == '/password_protected':