From 88d9c05e3c9fa7388d50554b48f5470a395bd94f Mon Sep 17 00:00:00 2001 From: arvidn Date: Thu, 9 Jan 2020 15:41:47 +0100 Subject: [PATCH] expand IPv4 in expand_unspecified_address --- simulation/test_tracker.cpp | 4 ++-- src/session_impl.cpp | 15 ++++++--------- test/test_listen_socket.cpp | 18 +++++++++++++++--- test/test_session.cpp | 7 ++++--- test/test_tracker.cpp | 12 ++++++++++-- test/udp_tracker.cpp | 8 ++++---- test/web_server.py | 4 +--- 7 files changed, 42 insertions(+), 26 deletions(-) diff --git a/simulation/test_tracker.cpp b/simulation/test_tracker.cpp index daa93a0e2..7a773c809 100644 --- a/simulation/test_tracker.cpp +++ b/simulation/test_tracker.cpp @@ -542,7 +542,7 @@ void test_udpv6_support(char const* listen_interfaces TORRENT_TEST(ipv6_support) { // 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) @@ -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 // 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) diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 6a900a5a2..4a0951b5e 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -238,27 +238,24 @@ namespace aux { } // 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 - // by prohibiting creating a listen socket on [::]. Instead the list of + // on each interface they use to talk to the DHT. This is enforced + // 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. - // 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 const ifs , std::vector& eps) { 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 unspecified_eps(unspecified_begin, eps.end()); eps.erase(unspecified_begin, eps.end()); for (auto const& uep : unspecified_eps) { + bool const v4 = uep.addr.is_v4(); for (auto const& ipface : ifs) { if (!ipface.preferred) continue; - if (ipface.interface_address.is_v4()) + if (ipface.interface_address.is_v4() != v4) continue; if (!uep.device.empty() && uep.device != ipface.name) continue; @@ -4943,7 +4940,7 @@ namespace aux { } } 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) { diff --git a/test/test_listen_socket.cpp b/test/test_listen_socket.cpp index 747291105..6e80c58f3 100644 --- a/test/test_listen_socket.cpp +++ b/test/test_listen_socket.cpp @@ -306,6 +306,12 @@ TORRENT_TEST(expand_unspecified) auto v4_nossl = ep("0.0.0.0", 6881); 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_ssl = ep("::", 6884, tp::ssl); 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); - TEST_EQUAL(eps.size(), 8); - TEST_CHECK(std::count(eps.begin(), eps.end(), v4_nossl) == 1); - TEST_CHECK(std::count(eps.begin(), eps.end(), v4_ssl) == 1); + TEST_EQUAL(eps.size(), 12); + TEST_CHECK(std::count(eps.begin(), eps.end(), v4_g1_nossl) == 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_ssl) == 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_loopb_ssl) == 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_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 auto v6_g_nossl_dev = ep("2601:646:c600:a3:d250:99ff:fe0c:9b74", 6883, "eth0"); diff --git a/test/test_session.cpp b/test/test_session.cpp index 492f8016d..ecc5cbde0 100644 --- a/test/test_session.cpp +++ b/test/test_session.cpp @@ -541,18 +541,19 @@ TORRENT_TEST(reopen_network_sockets) settings_pack p = settings(); 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_natpmp, true); 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); - TEST_CHECK(count_alerts(s, 0, 4)); + TEST_CHECK(count_alerts(s, 0, 2)); s.reopen_network_sockets({}); diff --git a/test/test_tracker.cpp b/test/test_tracker.cpp index 4f4a181b8..e3f288d2c 100644 --- a/test/test_tracker.cpp +++ b/test/test_tracker.cpp @@ -46,6 +46,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/announce_entry.hpp" #include "libtorrent/torrent.hpp" #include "libtorrent/aux_/path.hpp" +#include "libtorrent/socket_io.hpp" #include @@ -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::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); 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) { - 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) @@ -667,7 +675,7 @@ void test_stop_tracker_timeout(int const timeout) settings_pack p = settings(); p.set_bool(settings_pack::announce_to_all_trackers, 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); lt::session s(p); diff --git a/test/udp_tracker.cpp b/test/udp_tracker.cpp index a4176f51a..157cdf65c 100644 --- a/test/udp_tracker.cpp +++ b/test/udp_tracker.cpp @@ -146,10 +146,10 @@ struct udp_tracker } else { - detail::write_uint8(1, ptr); - detail::write_uint8(3, ptr); - detail::write_uint8(3, ptr); - detail::write_uint8(7, ptr); + detail::write_uint8(127, ptr); + detail::write_uint8(0, ptr); + detail::write_uint8(0, ptr); + detail::write_uint8(2, ptr); detail::write_uint16(1337, ptr); } m_socket.send_to(boost::asio::buffer(buffer diff --git a/test/web_server.py b/test/web_server.py index 57a46bc7e..79ae8c2d5 100644 --- a/test/web_server.py +++ b/test/web_server.py @@ -42,7 +42,7 @@ class http_handler(BaseHTTPRequestHandler): def do_GET(s): - print('INCOMING-REQUEST: ', s.requestline) + print('INCOMING-REQUEST [from: {}]: {}'.format(s.request.getsockname(), s.requestline)) print(s.headers) sys.stdout.flush() @@ -55,8 +55,6 @@ class http_handler(BaseHTTPRequestHandler): s.path = s.path[s.path.find('/'):] file_path = os.path.normpath(s.path) - print(file_path) - print(s.path) sys.stdout.flush() if s.path == '/password_protected':