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)
{
// 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)

View File

@ -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<ip_interface const> const ifs
, std::vector<listen_endpoint_t>& 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<listen_endpoint_t> 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)
{

View File

@ -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");

View File

@ -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({});

View File

@ -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 <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::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);

View File

@ -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

View File

@ -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':